本文介绍了String类、StringBuffer类、StringBuilder类的区别和各自的使用方法。

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
65
66
67
68
69
70
71
72
73
74
75
public class StringDemo {
public static void main(String[] args) {
String s0 = "hello world";
String s1 = "Hello world";
String s2 = new String("Hello world");
System.out.println(s1.equals(s2)); //true 比较内容
System.out.println(s1 == s2); //false 比较地址
System.out.println(s0.equalsIgnoreCase(s1)); //忽略大小写比较

String s3 = s1 + s2; //用+号拼接 性能较低
System.out.println(s3);
String s4 = s1.concat(s2); //contact方法拼接
System.out.println(s4);

String s5 = "aabytea";
for(int i = 0; i < s5.length(); ++i){
System.out.println(s5.charAt(i)); //取String的单个字符
}
char[] arr = s5.toCharArray(); //String转字符数组
String s6 = "aabytec";
System.out.println(s5.compareTo(s6)); //比较字符串的字典序 s5 - s6
String s7 = "abbccddeeffggabcd";
//str.indexOf(char ch, int fromIndex) 返回str从索引fromIndex开始 第一次出现字符ch的位置
//省略fromIndex则默认从0开始
System.out.println(s7.indexOf('c',0)); //4
//str.indexOf(String s, int fromIndex) 返回str从索引fromIndex开始 第一次出现字符串s的位置
System.out.println(s7.indexOf("abcd",0)); //13
System.out.println(s7.contains("abcd")); //true 是否包含字串
//同理 lastIndexOf 从反向搜索
System.out.println(s7.lastIndexOf("dde")); //5
System.out.println(s7.lastIndexOf('b')); //14
System.out.println(s7.lastIndexOf('b',5)); //2
String s8 = "Java Php MySQL Java";
String s9 = s8.replaceAll("Java","Python"); //Python Php MySQL Python
System.out.println(s9);
System.out.println(s8.startsWith("Java")); //true
System.out.println(s8.endsWith("Java")); //true
String s10 = "abcdefghiJKLMN";
System.out.println(s10.substring(2,8)); //cdefgh 截取子串
System.out.println(s10.toUpperCase()); //转大写 ABCDEFGHIJKLMN
System.out.println(s10.toLowerCase()); //转小写 abcdefghijklmn
//将字符串按照某个分隔符分割为数组
String str1 = "Tom,Lily,Jerry,Lucy,Kyle";
String[] strArr = str1.split(",");
for(String s : strArr){
System.out.println(s);
}
//替换内容
String str2 = str1.replace("Tom","John");
System.out.println(str1);
System.out.println(str2);
String str3 = "abcdeabcde123456789";
String str4 = str3.replaceAll("a","MMM");
System.out.println(str4);
String str5 = str3.replaceAll("\\d","*");
System.out.println(str5);
String str6 = str3.replaceAll("\\w","*");
System.out.println(str6);
//去除字符串前后的空格(包括制表符、换行符)
String str7 = " Java \n";
System.out.println(str7);
System.out.println(str7.trim());
//正则表达式去除所有空格
System.out.println(str7.replaceAll("\\s",""));
//String 和 int double之间的转换
String numStr1 = "1234";
int num1 = Integer.parseInt(numStr1);
String numStr2 = "564.45";
double num2 = Double.parseDouble(numStr2);
System.out.println(num1 + num2); //1798.45
Integer n = Integer.valueOf(numStr1);
String numStr3 = Integer.toString(n); //Integer转String
System.out.println(numStr3);
}
}

StringBuffer类:

  1. StringBuffer类是对String类的增强,它还是lang包中的,即java.lang.StringBuffer类。
  2. StringBuffer类代表可变的字符串,可以对字符串的内容进行增删。
  3. StringBuffer类的很多方法都与String类相同,只不过StringBuffer是可变长度的。
  4. StringBuffer是一个容器。
  5. StringBuffer是final类,不能被继承。

常用方法:

方法 功能
public StringBuffer append(String str) 将指定的字符串追加到此字符序列
public StringBuffer delete(int start, int end) 移除此序列的子字符串中的字符。该子字符串从指定的 start 处开始,一直到索引 end - 1 处的字符,如果不存在这种字符,则一直到序列尾部。如果 start 等于 end,则不发生任何更改
public StringBuffer replace(int start,int end,String str) 使用给定 String 中的字符替换此序列的子字符串中的字符。该子字符串从指定的 start 处开始,一直到索引 end - 1 处的字符,如果不存在这种字符,则一直到序列尾部。先将子字符串中的字符移除,然后将指定的 String 插入 start。(如果需要,序列将延长以适应指定的字符串)
public int indexOf(String str) 返回第一次出现的指定子字符串在该字符串中的索引
public StringBuffer insert(int offset, String str) 将字符串插入此字符序列中。 按顺序将 String 参数中的字符插入此序列中的指定位置,将该位置处原来的字符向后移,此序列将增加该参数的长度。如果 str 为 null,则向此序列中追加 4 个字符 “null”
public char charAt(int index) 返回此序列中指定索引处的 char 值。第一个 char 值在索引 0 处,第二个在索引 1 处,依此类推,这类似于数组索引。 index 参数必须大于等于 0,且小于此序列的长度
public int length() 返回长度(字符数)不是容量

代码演示:

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
public class StringBufferDemo {
public static void main(String[] args) {
//初始化
StringBuffer s = new StringBuffer("aabyteMMMM");
//拼接
s.append("000");
s.append("Lucy").append(100).append(true).append(10.5);
System.out.println(s); // aabyteMMMM000Lucy100true10.5
//删除
//删除索引为 >= start && < end 处的字符
//解读: 删除 8~13 的字符 [8, 13)
s.delete(8, 13);
System.out.println(s); // aabyteMMLucy100true10.5
//修改
//使用 MySQL 替换 索引2-5的字符 [2,5)
s.replace(2, 5, "MySQL");
System.out.println(s); // aaMySQLeMMLucy100true10.5
//查找
//查找指定的子串在字符串第一次出现的索引,如果找不到返回-1
int indexOf = s.indexOf("Lucy");
System.out.println(indexOf);// 10
//插入
//解读,在索引为9的位置插入 "JAVA",原来索引为9的内容自动后移
s.insert(9, "JAVA");
System.out.println(s); // aaMySQLeMJAVAMLucy100true10.5
//长度
//返回字符的个数,与容量无关
System.out.println(s.length()); // 29
System.out.println(s); // aaMySQLeMJAVAMLucy100true10.5
// charAt()
// 返回此序列中指定索引处的 char 值,与容量无关
System.out.println(s.charAt(0)); // a
}
}

运行结果:

1
2
3
4
5
6
7
8
aabyteMMMM000Lucy100true10.5
aabyteMMLucy100true10.5
aaMySQLeMMLucy100true10.5
10
aaMySQLeMJAVAMLucy100true10.5
29
aaMySQLeMJAVAMLucy100true10.5
a

StringBuilder类:

  1. StringBuilder 类保存了一个可变的字符序列。此类提供了一个与 StringBuffer 类兼容的API。该类被设计用作 StringBuffer 类的一个简易替换,用在字符串缓冲区被单个线程使用的时候。

  2. StringBuilder 类不保证同步(即不是线程安全的),但它要比StringBuffer 类的速度快,在单线程中,优先使用该类。

  3. StringBuilder 类的直接父类 是 AbstractStringBuilder 类。

  4. StringBuilder 实现了 Serializable 接口,代表了 StringBuffer 类的对象可以串行化【即可以进行网络编程】。

  5. 在父类 AbstractStringBuilder 中包含属性 char[] value,没有 final 修饰(与 String 类不同),因此该 value 数组存储字符串的位置在堆内存中,而不是在方法区的常量池中。

  6. StringBuilder 类是一个 final 类,不能被继承。

  7. 因为StringBuilder 类对象的字符序列是存储在 char[] value 属性中的,所以在改变字符序列时(增加/删除), 不用每次都更换对象地址(即不是每次创建新对象), 因此其效率高于 String 类。

  8. StringBuilder 类没有实现多线程同步(即它不是线程安全的)。

String、StringBuffer 和 StringBuilder 的比较:

  1. StringBuilder和StringBuffer非常类似,均代表可变的字符序列,而且方法也一样。
  2. String: 不可变字符序列,效率低,但是复用率高。
  3. StringBuffer: 可变字符序列、效率较高(增删)、线程安全。
  4. StringBuilder: 可变字符序列、效率最高、但线程不安全。
  5. 每次对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
public class StringBuilderDemo {
public static void main(String[] args) {
//初始化
StringBuilder s = new StringBuilder("aabyteMMMM");
//拼接
s.append("000");
s.append("Lucy").append(100).append(true).append(10.5);
System.out.println(s); // aabyteMMMM000Lucy100true10.5
//删除
//删除索引为 >= start && < end 处的字符
//解读: 删除 8~13 的字符 [8, 13)
s.delete(8, 13);
System.out.println(s); // aabyteMMLucy100true10.5
//修改
//使用 MySQL 替换 索引2-5的字符 [2,5)
s.replace(2, 5, "MySQL");
System.out.println(s); // aaMySQLeMMLucy100true10.5
//查找
//查找指定的子串在字符串第一次出现的索引,如果找不到返回-1
int indexOf = s.indexOf("Lucy");
System.out.println(indexOf);// 10
//插入
//解读,在索引为9的位置插入 "JAVA",原来索引为9的内容自动后移
s.insert(9, "JAVA");
System.out.println(s); // aaMySQLeMJAVAMLucy100true10.5
//长度
//返回字符的个数,与容量无关
System.out.println(s.length()); // 29
System.out.println(s); // aaMySQLeMJAVAMLucy100true10.5
// charAt()
// 返回此序列中指定索引处的 char 值,与容量无关
System.out.println(s.charAt(0)); // a
}
}
  • 字符串存在大量修改操作 + 单线程情况 = 推荐使用StringBuilder
  • 字符串存在大量修改操作 + 多线程情况 = 推荐使用StringBuffer
  • 字符串很少修改 + 被多个对象引用 = 推荐使用String