一、StringBuffer 类
1. 基本概念
(1)StringBuffer 类对象代表一个可变的字符序列,可以对字符串内容进行增删等操作;
(2)StringBuffer 类中的很多方法与 String 类中的方法相同,但它是可变长度的;
(3)StringBuffer 类对象是一个容器。
- 使用细节:
1. StringBuffer 类的直接父类 是 AbstractStringBuilder 类。
2. StringBuffer 实现了 Serializable 接口,代表了 StringBuffer 类的对象可以串行化【即可以进行网络编程】。
3. 在父类 AbstractStringBuilder 中包含属性 char[] value,没有 final 修饰(与 String 类不同),因此该 value 数组存储字符串的位置在堆内存中,而不是在方法区的常量池中。
4. StringBuffer 类是一个 final 类,不能被继承。
5. 因为StringBuffer 类对象的字符序列是存储在 char[] value 属性中的,所以在改变字符序列时(增加/删除), 不用每次都更换对象地址(即不是每次创建新对象), 因此其效率高于 String 类。
6. StringBuffer 类实现了多线程同步(即它是线程安全的)。
2. String 类和 StringBuffer 类的区别
(1)String 类对象保存的是字符串常量(在常量池中),里面的字符序列不能被更改,每次对字符串的改变,都是在常量池中创建了一个新的字符串(对象/空间/地址),而原有的字符串依然存在。
(2)StringBuffer 类对象是一个容积可变的容器,它用来保存字符序列(在堆内存中),但其保存的字符序列可以改变,每次对字符串的改变,都是在原有的字符串上进行操作,而不用新创建一个字符串(对象/空间/地址),原有的字符串不再存在了。
- String对象 和 StringBuffer 对象的相互转换
// String ——> StringBuffer
String str = "hello tom";
// 方式1: 使用 StringBuffer 类的构造器
// 注意: 返回的才是StringBuffer对象,对str 本身没有影响
StringBuffer stringBuffer = new StringBuffer(str);
// 方式2: 使用 StringBuffer 类的 append 方法
StringBuffer stringBuffer1 = new StringBuffer();
stringBuffer1 = stringBuffer1.append(str);
// StringBuffer --> String
StringBuffer stringBuffer3 = new StringBuffer("lineryue");
// 方式1: 使用 String 类的构造器
String s = new String(stringBuffer3);
// 方式1: 使用 StringBuffer 类的 toString 方法
String s1 = stringBuffer3.toString();
3. StringBuffer 类常用方法
- 如下表:
方法 | 功能 |
---|---|
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() | 返回长度(字符数)不是容量。 |
- 代码演示:
public class StringBufferMethod {
public static void main(String[] args) {
StringBuffer s = new StringBuffer("hello");
// 增
s.append(','); // "hello,"
s.append("张三丰");// "hello,张三丰"
s.append("赵敏").append(100).append(true).append(10.5);// "hello,张三丰赵敏100true10.5"
System.out.println(s);// "hello,张三丰赵敏100true10.5"
// 删
/*
* 删除索引为 >= start && < end 处的字符
* 解读: 删除 11~14的字符 [11, 14)
*/
s.delete(11, 14);
System.out.println(s);// "hello,张三丰赵敏true10.5"
// 改
// 解读,使用 周芷若 替换 索引9-11的字符 [9,11)
s.replace(9, 11, "周芷若");
System.out.println(s);// "hello,张三丰周芷若true10.5"
// 查
// 查找指定的子串在字符串第一次出现的索引,如果找不到返回-1
int indexOf = s.indexOf("张三丰");
System.out.println(indexOf);// 6
// 插
// 解读,在索引为9的位置插入 "赵敏",原来索引为9的内容自动后移
s.insert(9, "赵敏");
System.out.println(s);// "hello,张三丰赵敏周芷若true10.5"
// 长度
// 返回字符的个数,与容量无关
System.out.println(s.length());// 22
System.out.println(s);
// charAt()
// 返回此序列中指定索引处的 char 值,与容量无关
System.out.println(s.charAt(0);// h
}
}
二、StringBuilder 类
1. 基本概念
(1)StringBuilder 类保存了一个可变的字符序列。此类提供了一个与 StringBuffer 类兼容的API。该类被设计用作 StringBuffer 类的一个简易替换,用在字符串缓冲区被单个线程使用的时候。
(2) StringBuilder 类不保证同步(即不是线程安全的),但它要比StringBuffer 类的速度快,在单线程中,优先使用该类。
- 使用细节:
1. StringBuilder 类的直接父类 是 AbstractStringBuilder 类。
2. StringBuilder 实现了 Serializable 接口,代表了 StringBuffer 类的对象可以串行化【即可以进行网络编程】。
3. 在父类 AbstractStringBuilder 中包含属性 char[] value,没有 final 修饰(与 String 类不同),因此该 value 数组存储字符串的位置在堆内存中,而不是在方法区的常量池中。
4. StringBuilder 类是一个 final 类,不能被继承。
5. 因为StringBuilder 类对象的字符序列是存储在 char[] value 属性中的,所以在改变字符序列时(增加/删除), 不用每次都更换对象地址(即不是每次创建新对象), 因此其效率高于 String 类。
6. StringBuilder 类没有实现多线程同步(即它不是线程安全的)。
2. String、StringBuffer 和 StringBuilder 的比较
- 比较如下:
- 代码演示:
public class StringVsStringBufferVsStringBuilder {
public static void main(String[] args) {
long startTime = 0L;
long endTime = 0L;
StringBuffer buffer = new StringBuffer("");
startTime = System.currentTimeMillis();
// StringBuffer 拼接 20000次
for (int i = 0; i < 80000; i++) {
buffer.append(String.valueOf(i));
}
endTime = System.currentTimeMillis();
System.out.println("StringBuffer的执行时间:" + (endTime - startTime));
StringBuilder builder = new StringBuilder("");
startTime = System.currentTimeMillis();
// StringBuilder 拼接 20000次
for (int i = 0; i < 80000; i++) {
builder.append(String.valueOf(i));
}
endTime = System.currentTimeMillis();
System.out.println("StringBuilder的执行时间:" + (endTime - startTime));
String text = "";
startTime = System.currentTimeMillis();
// String 拼接 20000
for (int i = 0; i < 80000; i++) {
text = text + i;
}
endTime = System.currentTimeMillis();
System.out.println("String的执行时间:" + (endTime - startTime));
}
}
- String、StringBuffer 和 StringBuilder 的选择
总结
- 本文是小白博主在学习B站韩顺平老师的Java网课时整理总结的学习笔记,在这里感谢韩顺平老师的网课,如有有兴趣的小伙伴也可以去看看。
- 本文详细解释了 StringBuffer和StringBuilder类 的概念与使用,并讲解了 StringBuffer和StringBuilder类还有String类 相互转换的方法和区别,还举了很多例子,希望小伙伴们看后能有所收获!
- 最后,如果本文有什么错漏的地方,欢迎大家批评指正!一起加油!!我们下一篇博文见吧!