【Java基础】了解String

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关键字创建字符串:

  1. 先去 方法区-字符串常量池中用 equals()方法找是否有 "new"的字符串,
    1. 如果有,继续下一步;
    2. 如果没有,则在 方法区-字符串常量池中创建一个 "new"的字符串,继续下一步;
  1. 再去 堆区创建一个 "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"
复制代码

猜你喜欢

转载自juejin.im/post/7032456364437798925