共计 3337 个字符,预计需要花费 9 分钟才能阅读完成。
第三阶段 JAVA 常见对象的学习
StringBuffer 和 StringBuilder 类
(一) StringBuffer 类的概述
(1) 基本概述
下文以 StringBuffer 为例
前面我们用字符串做拼接,比较耗时并且也耗内存(每次都会构造一个新的 string 对象),而这种拼接操作又是比较常见的,为了解决这个问题,Java 就提供了两个字符串缓冲区类。StringBuffer 和 StringBuilder 供我们使用。
简单比较:
String 长度大小不可变
StringBuffer 长度可变、线程安全、速度较慢
StringBuilder 长度可变、线程不安全、速度最快
—————————————————————————————————————–
解释:
- 在执行速度方面的比较:StringBuilder > StringBuffer
- StringBuffer 与 StringBuilder,他们是字符串变量,是可改变的对象,每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,不像 String 一样创建一些对象进行操作,所以速度就快了。
- StringBuilder:线程非安全的
StringBuffer:线程是安全的(synchronized 关键字进行修饰)
当我们在字符串缓冲区被多个线程使用时,JVM 不能保证 StringBuilder 的操作是安全的,虽然他的速度最快,但是可以保证 StringBuffer 是可以正确操作的。当然大多数情况下就是我们是在单线程下进行的操作,所以大多数情况下是建议用 StringBuilder 而不用 StringBuffer 的,就是速度的原因。
对于三者使用的总结:
1. 如果要操作少量的数据用 = String
2. 单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
3. 多线程操作字符串缓冲区 下操作大量数据 = StringBuffer
(2) StringBuffer 的构造方法
// 无参构造方法
StringBuffer()
// 指定容量的字符串缓冲区对象
StringBuffer(int size)
// 指定字符串内容的字符串缓冲区对象
StringBuffer(String str)
(二) StringBuffer 类的功能
(1) 添加功能
// 可以把任意类型添加到字符串缓冲区里,并且返回字符串缓冲区本身(this)public StringBuffer append (String str)
// 在 offset 位置把任意类型的数据插入到字符串缓冲区中, 并且返回字符串缓冲区本身(this)public StringBuffer insert(int offset,String str)
(2) 删除功能
// 删除指定位置的字符,并且返回本身
public StringBuffer deleteCharAt(int index)
// 删除从指定位置开始指定位置结束的内容,并且返回本身
public StringBuffer delete(int start, int end)
(3) 替换功能
// 从 start 到 end 用 str 代替
public StringBuffer replace(int start,int end,String str)
(4) 反转功能
//Eg: 好你界世 → 世界你好
public StringBuffer reverse()
(5) 截取功能
// 从 start 位置开始截取, 取以后字符串, 但不返回本身,原数据不影响
public String substring(int start)
// 截取 start 到 end 之间的字符串
Publci Stirng substring(int start, int end)
(三) String 和 StringBuffer 类相互转换
(1) 转换原因:
String → StringBuffer 是为了使用后者的功能
StringBuffer → String 可能需要后者的类型
(2) 转换方式
※ String → StringBuffer
String s =“Hello”// 通过构造方法
StringBuffer a = new StringBuffer(s);
// 通过 append() 方法
StringBuffer a = new StringBuffer();
a.append(s);
※ StringBuffer → String
StringBuffer buffer = new StringBuffer(“java”)
// 通过构造方法
String str = new String (buffer);
// 通过 toString() 方法
String str = buffer.toString();
(四)“+”和 StringBuilder 类的爱恨情仇
首先 java 并不支持运算符重载。
(String 类中的“+”“+=”是 java 中仅有的两个重载过的运算符)
所以我们可以通过“+”符号 将多个字符串进行拼接
将这段代码利用 javap -c filename 反编译
我们可以看到代码被编译器自动优化成使用 StringBuilder 方式拼接
运行效率得到了保证
下面一个案例 数组拼接成指定格式的字符串 代码中使用了循环语句
// 在循环中通过 String 拼接字符串
public class StringBuilderDemo {public static void main(String[] args) {String[] arr = {"Hello", "World", "!!!"};
String s1 = arrayToString(arr);
System.out.println(s1);
}
public static String arrayToString(String[] arr) {
String s = "";
s += "[";
for (int x = 0; x < arr.length; x++) {if (x == arr.length - 1) {s += arr[x];
} else {s += arr[x];
s += ",";
}
}
s += "]";
return s;
}
}
// 运行结果
[Hello, World, !!!]
使用 String 方式进行拼接,我们反编译可以看到,StringBuilder 被创建在循环的内部,这意味着每循环一次就会创建一次 StringBuilder 对象,这可是一个糟糕的事情。
// 在循环中使用 StringBuilder 拼接字符串
public class StringBuilderDemo2 {public static void main(String[] args) {String[] arr = {"Hello", "World", "!!!"};
String s1 = arrayToString(arr);
System.out.println(s1);
}
public static String arrayToString(String[] arr) {StringBuilder s = new StringBuilder();
s.append("[");
for (int x = 0; x < arr.length; x++) {if (x == arr.length - 1) {s.append(arr[x]);
} else {s.append(arr[x]);
s.append(",");
}
}
s.append("]");
return s.toString();}
}
// 运行结果
[Hello, World, !!!]
使用 StringBuilder 方式进行拼接,反汇编代码,可以看到,不仅循环部分的代码更为简洁,而且它只生成了一个 StringBuilder 对象。显式的创建 StringBuilder 对象还允许你预先为其指定大小。可以避免多次重新分配缓冲。
总结:
如果字符串操作比较简单,就可以使用“+”运算符操作,编译器会为你合理的构造出最终的字符串结果
如果使用循环语句 最好自己手动创建一个 StringBuilder 对象,用它来构最终结果
结尾:
如果内容中有什么不足,或者错误的地方,欢迎大家给我留言提出意见, 蟹蟹大家!^_^
如果能帮到你的话,那就来关注我吧!(系列文章均会在公众号第一时间更新)
在这里的我们素不相识,却都在为了自己的梦而努力 ❤
一个坚持推送原创 Java 技术的公众号:理想二旬不止