String_StringBuilder_StringBuffer 区别
1.String:
String类是final修饰的,属于不可变(immutable)类,每次对原对象操作都会产生新的String对象。
源码中String类的定义:private final char value[];
可以看出用于存放字符的数组被声明为 final 的,因此只能赋值一次,不可再更改。
2.StringBuffer 和 StringBuilder区别:
两者都继承了一个抽象的字符串父类:AbstractStringBuilder。
StringBuffer 和 StringBuilder 它们都属于可变的字符串,都是在原对象上进行操作。
区别1:线程安全
StringBuffer:线程安全,StringBuilder:线程不安全。
因为 StringBuffer 的所有公开方法都是 synchronized 修饰的,而 StringBuilder 没有 修饰。
StringBuffer 的 append()方法源码:
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
区别2:缓冲区
StringBuffer 的 toString()方法源码:
private transient char[] toStringCache; @Override
public synchronized String toString() {
if (toStringCache == null) {
toStringCache = Arrays.copyOfRange(value, 0, count);
}
return new String(toStringCache, true);
}
StringBuilder 的 toString()方法源码:
@Override
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
StringBuffer 每次获取 toString 都会直接使用缓存区的 toStringCache 值来构造一个字符串。
而 StringBuilder 则每次都需要复制一次字符数组,再构造一个字符串。
所以,缓存冲这也是对 StringBuffer 的一个优化吧,不过 StringBuffer 的这个toString() 方法仍然是同步的。
区别3:性能
既然 StringBuffer 是线程安全的,它的所有公开方法都是同步的,StringBuilder 是没有对方法加锁同步的,
因此性能上:StringBuilder > StringBuffer > String。
3.使用场景
1. 基本原则:如果要操作少量的数据,用String ;单线程操作大量数据,用StringBuilder ;多线程操作大量数据,用StringBuffer。
2. 不要使用String类的 "+" 来进行频繁的拼接,因为那样的性能极差的,应该使用StringBuffer或StringBuilder类,这在Java的优化上是一条比较重要的原则。
例如:
String result = "";
for (String s : hugeArray) {
result = result + s;
}
// 使用StringBuilder
StringBuilder sb = new StringBuilder();
for (String s : hugeArray) {
sb.append(s);
}
String result = sb.toString();
显然采用第二种方法效率更搞,因为第一种方法每次循环都会创建一个String result用于保存结果。
3. 为了获得更好的性能,在构造 StringBuffer 或 StringBuilder 时应尽可能指定它们的容量。
当然,如果你操作的字符串长度(length)不超过 16 个字符就不用了,当不指定容量(capacity)时默认构造一个容量为 16 的对象,不指定容量会显著降低性能。
4. StringBuilder 一般使用在方法内部来完成类似 + 功能,因为是线程不安全的,所以用完以后可以丢弃。
而StringBuffer 主要用在全局变量中。
5. 相同情况下使用 StringBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。
而在现实的模块化编程中,负责某一模块的程序员不一定能清晰地判断该模块是否会放入多线程的环境中运行,
因此:除非确定系统的瓶颈是在 StringBuffer 上,并且确定你的模块不会运行在多线程模式下,才可以采用 StringBuilder;否则还是用 StringBuffer。
最新文章
- U3D DrawCall优化手记
- 缓解 SQL Server has encountered 727 occurrence(s) of I/O requests taking longer than 15 seconds
- PHP中$_SERVER的详细参数
- Atitit 修改密码的功能流程设计 attilax总结
- 如何重新安装DEDECMS织梦系统
- Entity Framework CodeFirst尝试
- shell脚本之lnmp的搭建
- 下拉刷新--第三方开源--PullToRefresh
- (转)c语言_链表实例讲解(两个经典例子)
- RedirectFromLoginPage和FormsAuthenticationTicket的区别
- Character frequency
- UVa 11825 集合dp
- poj 1458 Common Subsequence(区间dp)
- 设计模式的征途—8.桥接(Bridge)模式
- awk的+=用法
- 回收 PV - 每天5分钟玩转 Docker 容器技术(152)
- navicat for mysql 破解方法
- [Swift]LeetCode872. 叶子相似的树 | Leaf-Similar Trees
- 五一之起一台服务器玩玩-u盘安装centos
- 【PaddlePaddle】自然语言处理:句词预测