【Java基础】了解String String特性 创建字符

String特性

「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战

不可修改

本来想着说 String不可修改的原因是 String类用 final修饰,导致不可修改;

但是之后看了下 StringBuilder类和 StringBuffer类源码,这些可变字符串类也是用 final关键词修饰的,反应过来不是这个原因;

那 String不可以修改的原因是什么呢?

结论是:String本质上是一个 字符数组常量。

【问题】 为什么把 String设计成不可修改呢?(用 final修饰)

从性能和安全两个角度来可以解释这个问题

安全:String对象作为 Java类库中最常用到的参数,假如不是 final修饰成不可修改,可以被任意篡改,会很危险;

在多线程的情况下,String也是线程安全的。

性能:String用 final修饰下,String的 hash值属性是唯一的,可以放心的对字符串进行缓存,提高性能;

字符串常量池也是基于 String的不可变才可以实现的,一般情况下,创建一个字符串,是从常量池中找,省去了创建新的字符串对象,直接引用常量池的对象即可。

创建字符串的两种方法

1
2
ini复制代码String s1 = "hello"
String s2 = new String("hello");

一道经典的面试题

1
2
3
4
5
6
7
ini复制代码String a1 = new String("new");
String a2 = new String("new");
String b = "";
String c = "";
System.out.println(a1==a2);//false
System.out.println(b==c);//true
System.out.println(b.equals(c));//true

【问题】 两种字符串创建方式有什么区别?

使用""引号创建字符串:

  • 会去 方法区-字符串常量池中用 equals()方法找是否有 “”的字符串,
    • 如果有,则直接返回该字符串。
      • 如果没有,则在 方法区-字符串常量池中创建一个 “”的字符串。

使用new关键字创建字符串:

  1. 先去 方法区-字符串常量池中用 equals()方法找是否有 “new”的字符串,
    1. 如果有,继续下一步;
      1. 如果没有,则在 方法区-字符串常量池中创建一个 “new”的字符串,继续下一步;
  1. 再去 堆区创建一个 “new”的字符串对象,返回堆区对象的引用。

扩展知识:通过字符串的 intern()方法可以获取字符串常量池中字符的地址。

字符串拼接

字符串拼接在项目中很常用到,但是使用不当会造成效率低下;

1
ini复制代码String s1 = "a"+"b";

本质上是创建 StringBuilder对象,使用 append()方法拼接起来,最后用,如果在循环中使用 “+”拼接会创建大量的临时 StringBuilder对象,严重影响性能

1
2
3
4
ini复制代码StringBuilder s = new StringBuilder();
s.append("a");
s.append("b");
s1=s.toString();

在进行大量字符串拼接时,正确的做法是建议使用 StringBuilder或者 StringBuffer。

字符串常用 API

「删除字符串前后空格」

1
2
ini复制代码String s1 = " abc "
s1.trim();// "abc"

「字母大小写转换」

1
2
3
ini复制代码String s1 = "aB"
s1.toLowerCase("ab");
s1.toUpperCase("AB");

「判断两个字符串是否相等」

1
2
3
4
ini复制代码String s1 = "s1";
String s2 = "S1";
s1.equals(s2);//false
s1.equalslgnoreCase(s2)//true,忽略大小写进行比较

「判断字符的开始与结束」

1
2
3
4
5
ini复制代码String s1 = "Java";
String s2 = "Ja";
String s3 = "va";
s1.startWith(s2);//true
s1.endWith(s3);//true

「字符串分割」

1
2
ini复制代码String str = "www.baidu.com";
temp = str.split("."); // [www,baidu,com]

「判断是否符合正则规则」

1
2
3
4
5
6
7
8
9
10
11
csharp复制代码// 转自菜鸟
String Str = new String("www.runoob.com");

System.out.print("返回值 :" );
System.out.println(Str.matches("(.*)runoob(.*)"));

System.out.print("返回值 :" );
System.out.println(Str.matches("(.*)google(.*)"));

System.out.print("返回值 :" );
System.out.println(Str.matches("www(.*)"));

「字符串长度」

1
2
ini复制代码String s1 = "s1";
s1.length();//2

「子串查找」

1
2
3
csharp复制代码String lol = "lol";
System.out.println("lol.indexOf("l") = " + lol.indexOf("l"));//0
System.out.println("lol.indexOf("l") = " + lol.lastIndexOf("l"));//2

「字符串截取」

1
2
ini复制代码String num = "num";
num.substring(1);//"um"

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%