String特性
「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战」
不可修改
本来想着说 String不可修改的原因是 String类用 final修饰,导致不可修改;
但是之后看了下 StringBuilder类和 StringBuffer类源码,这些可变字符串类也是用 final关键词修饰的,反应过来不是这个原因;
那 String不可以修改的原因是什么呢?
结论是:String本质上是一个 字符数组常量。
【问题】 为什么把 String设计成不可修改呢?(用 final修饰)
从性能和安全两个角度来可以解释这个问题
安全:String对象作为 Java类库中最常用到的参数,假如不是 final修饰成不可修改,可以被任意篡改,会很危险;
在多线程的情况下,String也是线程安全的。
性能:String用 final修饰下,String的 hash值属性是唯一的,可以放心的对字符串进行缓存,提高性能;
字符串常量池也是基于 String的不可变才可以实现的,一般情况下,创建一个字符串,是从常量池中找,省去了创建新的字符串对象,直接引用常量池的对象即可。
创建字符串的两种方法
String s1 = "hello"
String s2 = new String("hello");
复制代码
一道经典的面试题
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
关键字创建字符串:
- 先去 方法区-字符串常量池中用 equals()方法找是否有 "new"的字符串,
-
- 如果有,继续下一步;
- 如果没有,则在 方法区-字符串常量池中创建一个 "new"的字符串,继续下一步;
- 再去 堆区创建一个 "new"的字符串对象,返回堆区对象的引用。
扩展知识:通过字符串的 intern()
方法可以获取字符串常量池中字符的地址。
字符串拼接
字符串拼接在项目中很常用到,但是使用不当会造成效率低下;
String s1 = "a"+"b";
复制代码
本质上是创建 StringBuilder对象,使用 append()方法拼接起来,最后用,如果在循环中使用 "+"拼接会创建大量的临时 StringBuilder对象,严重影响性能
StringBuilder s = new StringBuilder();
s.append("a");
s.append("b");
s1=s.toString();
复制代码
在进行大量字符串拼接时,正确的做法是建议使用 StringBuilder或者 StringBuffer。
字符串常用 API
「删除字符串前后空格」
String s1 = " abc "
s1.trim();// "abc"
复制代码
「字母大小写转换」
String s1 = "aB"
s1.toLowerCase("ab");
s1.toUpperCase("AB");
复制代码
「判断两个字符串是否相等」
String s1 = "s1";
String s2 = "S1";
s1.equals(s2);//false
s1.equalslgnoreCase(s2)//true,忽略大小写进行比较
复制代码
「判断字符的开始与结束」
String s1 = "Java";
String s2 = "Ja";
String s3 = "va";
s1.startWith(s2);//true
s1.endWith(s3);//true
复制代码
「字符串分割」
String str = "www.baidu.com";
temp = str.split("."); // [www,baidu,com]
复制代码
「判断是否符合正则规则」
// 转自菜鸟
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(.*)"));
复制代码
「字符串长度」
String s1 = "s1";
s1.length();//2
复制代码
「子串查找」
String lol = "lol";
System.out.println("lol.indexOf("l") = " + lol.indexOf("l"));//0
System.out.println("lol.indexOf("l") = " + lol.lastIndexOf("l"));//2
复制代码
「字符串截取」
String num = "num";
num.substring(1);//"um"
复制代码