Java之String

一、特殊的 String 类

  1. 虽然是引用类型,但是可以像基础数据类型一样直接赋值(String s = "";
  2. 不可被继承,String 类被final修饰

二、String 常用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// 返回指定字符第一次出现的字符串内的索引,以指定的索引开始搜索
String.indexOf(int ch, int fromIndex);
// int

// 返回指定子字符串第一次出现的字符串内的索引
String.indexOf(String str);
// int

// 返回指定子串的第一次出现的字符串中的索引,从指定的索引开始
String.indexOf(String str, int fromIndex);
// int


// 返回指定字符的最后一次出现的字符串中的索引
String.lastIndexOf(int ch);
// int

// 返回指定字符的最后一次出现的字符串中的索引,从指定的索引开始向后搜索
String.lastIndexOf(int ch, int fromIndex);
// int

// 返回指定子字符串最后一次出现的字符串中的索引
String.lastIndexOf(String str);
// int

// 返回指定子字符串的最后一次出现的字符串中的索引,从指定索引开始向后搜索
String.lastIndexOf(String str, int fromIndex);
// int

// 字符串是否匹配给定的正则表达式
String.matches(String regex);
// boolean

// 返回从替换所有出现的导致一个字符串 oldChar在此字符串 newChar
String.replace(char oldChar, char newChar);
// String

// 将与字面目标序列匹配的字符串的每个子字符串替换为指定的字面替换序列
String.replace(CharSequence target, CharSequence replacement);
// String

// 用给定的替换替换与给定的 regular expression匹配的此字符串的每个子字符串
String.replaceAll(String regex, String replacement);
// String

// 用给定的替换替换与给定的 regular expression匹配的此字符串的第一个子字符串
String.replaceFirst(String regex, String replacement);
// String

// 将此字符串分割为给定的 regular expression的匹配
String.split(String regex);
// String[]

// 将这个字符串拆分为给定的 regular expression的匹配
String.split(String regex, int limit);
// String[]

// 返回一个字符串,该字符串是此字符串的子字符串
String.substring(int beginIndex);
// String

// 返回一个字符串,该字符串是此字符串的子字符串
String.substring(int beginIndex, int endIndex);
// String

案例分析

1
2
3
4
5
6
7
8
9
10
11
12
String s1 = "Hello";
String s2 = new String("Hello");
String s3 = s2.intern();
String s4 = "Hel" + "lo";
String sa = "Hel";
String sb = "lo";
String s5 = sa + sb;

System.out.println(s1 == s2);// false
System.out.println(s1 == s3);// true
System.out.println(s1 == s4);// true
System.out.println(s1 == s5);// false
  • String 的 intern() 方法会查找在常量池中是否存在一份 equal 相等的字符串,如果有则返回该字符串的引用,如果没有则添加自己的字符串进入常量池。
    (因为 s1 已经在常量池中创建了"Hello"字符串,所以 s2.intern() 的时候就去常量池中查找是否已经存在"Hello",存在则直接=原来的字符串,不存在则是一个新的存在,所以 s3=s1)
  • 虽然 s4 是动态拼接出来的,但所有参与拼接的部分都是已知的字面量,在编译期间,这种拼接会被优化,编译器直接帮你拼好,因此相等。
    (只有使用这种全部带引号、使用“+”连接产生的新字符串对象才会被加入字符串池中)
    (s4 在初始化的过程中,产生了一个或〇个对象,若常量池中早已存在该字符串,则直接指向常量池,否则使用字符串拼接优化,产生一个 StringBuffer 对象进行拼接,然后 toString(),存放到常量池中)
1
String s4 = new StringBuffer().append("Hel").append("lo").toString()
  • 虽然 s5 也是拼接,但 sa 和 sb 作为两个变量,都是不可预料的,并不会被优化,会存放到堆中。

三、Java 的字符串类比较

String、StringBuffer、StringBuilder

  1. 执行速度比较(例如字符串的组合速度):StringBuilder > StringBuffer > String
  2. StringBuilder – 非线程安全;StringBuffer – 线程安全
    (因为 StringBuffer 为保证线程安全而牺牲了性能,所以当我们在不用考虑线程的情况下,尽量使用 StringBuilder)

总结

  • 如果要操作少量的数据 → String
  • 不考虑线程安全处理字符串缓冲区下大量数据 → StringBuilder
  • 需考虑线程安全处理字符串缓冲区下大量数据 → StringBuffer

四、Java 常量池与 String 类

Java 中的常量池实际上分为两种形态:静态常量池和运行时常量池。
静态常量池即是 *.class 文件中的常量池,用来存放方法名称、字段名称等。
运行时常量池则是我们常说的常量池,用来存放常量(final 关键字修饰的变量)和字符串等,避免频繁的创建和销毁对象而影响系统性能,实现了对象的共享(即大家用的都是同一个东西)。





  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2022-2024 Liangxj
  • 访问人数: | 浏览次数: