String,StringBuilder,StringBuffer区别
一、String,StringBuilder,StringBuffer的大概了解
大家知道String,StringBuilder,StringBuffer三个的基本应用场景。
- String会一直创建新对象,因此频繁创建对象的场景不适合用。
- StringBuilder则可以避免这个情况,因此频繁对字符串操作的场景使用StringBuilder比较合适。
- 但是StringBuilder并不是线程安全的,如果要线程安全,需要使用StringBuffer。
二、为什么String会一直创建新对象?
private final char value[];
- String代码中,字符是存在一个 final 的 char value[]里面的。
- 由于final指定了存储的内从是固定的,因此如果有append之类的操作的话要重新开辟新的内存。
- 要注意的是即使 value[]是final的,它也是可以改变里面的内容的。
下面这写法是正确的。不会报错。
final char[] ss = {'a', 'b', 'c'};
ss[0] = 'b';
ss[1] = 'c';
但是String类并没有提供这么一个接口能直接修改value数组。其中的replace是返回了一个新的String 对象。并不是在原先的数组上进行修改。
public String replace(char oldChar, char newChar) {
if (oldChar != newChar) {
int len = value.length;
int i = -1;
char[] val = value; /* avoid getfield opcode */
while (++i < len) {
if (val[i] == oldChar) {
break;
}
}
if (i < len) {
char buf[] = new char[len];
for (int j = 0; j < i; j++) {
buf[j] = val[j];
}
while (i < len) {
char c = val[i];
buf[i] = (c == oldChar) ? newChar : c;
i++;
}
return new String(buf, true);
}
}
return this;
}
三、StringBuilder中的主要内容
这个类继承了AbstractStringBuilder。AbstractStringBuilder里面封装了大部分内容。初始化大小为16个字符。
1、相比较String中的value,这个不是final 类型的。
char[] value;
2、newCapacity方法。
- 将原始的capacity*2+2
- 判断新的容量是不是合法
- 最大容量不会超过MAX_ARRAY_SIZE。MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8.
private int newCapacity(int minCapacity) {
// overflow-conscious code
int newCapacity = (value.length << 1) + 2;
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
? hugeCapacity(minCapacity)
: newCapacity;
}
3、append方法
其实最终调用了System.arrayCopy将append中的String value copy到了StringBuilder 中的 value。
public AbstractStringBuilder append(StringBuffer sb) {
if (sb == null)
return appendNull();
int len = sb.length();
ensureCapacityInternal(count + len);
sb.getChars(0, len, value, count);
count += len;
return this;
}
最终调用getChars方法。
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
if (srcBegin < 0) {
throw new StringIndexOutOfBoundsException(srcBegin);
}
if (srcEnd > value.length) {
throw new StringIndexOutOfBoundsException(srcEnd);
}
if (srcBegin > srcEnd) {
throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
}
System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
}
四、StringBuffer中的主要内容
这个类同样继承了AbstractStringBuilder。
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
但是几乎所有的方法都加了同步。因此是线程安全的。
1、append
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
2、chartAt
@Override
public synchronized char charAt(int index) {
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
return value[index];
}
其中StringBuffer里面有个 char [] toStringCache。当调用toString的时候,这个就会缓存StringBuffer的内容。当对StringBuffer有修改的时候,这个数组就会设定为null。
private transient char[] toStringCache;
String,StringBuilder,StringBuffer区别的更多相关文章
- String StringBuilder StringBuffer区别
String StringBuilder StringBuffer String类是final类,不可以被继承,且它的成员方法也是final方法,当一个字符串对象进行操作操作时,任何的改变不会影响到这 ...
- JAVA记录-String/StringBuilder/StringBuffer区别
- String, StringBuilder, StringBuffer问题
1. 区别 String为字符串常量,而StringBuilder和StringBuffer都是字符串变量,其中StringBuilder线程非安全,StringBuffer线程安全. 每次对 Str ...
- String,StringBuilder,StringBuffer的对比测试
public class TestString { private static final int COUNT = 10000000; public static void main(String ...
- JDK源码分析系列---String,StringBuilder,StringBuffer
JDK源码分析系列---String,StringBuilder,StringBuffer 1.String public final class String implements java.io. ...
- java中String StringBuilder StringBuffer比较和效率(性能)测试
string stringbuilder stringbuffer三者的区别 从JDK源码看,String.StringBuilder.StringBuffer都是存放在char[] 数组字符串. 简 ...
- 深入源码剖析String,StringBuilder,StringBuffer
[String,StringBuffer,StringBulider] 深入源码剖析String,StringBuilder,StringBuffer [作者:高瑞林] [博客地址]http://ww ...
- difference among String,StringBuilder,StringBuffer
difference among String,StringBuilder,StringBuffer String常用构造函数 String(byte[] bytes) String(byte[] b ...
- String Stringbuilder Stringbuffer的区别
String 字符串常量StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非线程安全) 简要的说, String 类型和 StringBuffer 类型的主要性能 ...
- java中string stringbuilder stringbuffer 的区别
1. String 类 String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间. String a = "a&qu ...
随机推荐
- Spring cloud config 使用gitHub或者gitee连接
1. 创建SpringCloud项目,引入对应的Spring-config-server对应的jar <dependency> <groupId>org.springframe ...
- BZOJ 1912: [Apio2010]patrol 巡逻 (树的直径)(详解)
题目: https://www.lydsy.com/JudgeOnline/problem.php?id=1912 题解: 首先,显然当不加边的时候,遍历一棵树每条边都要经过两次.那么现在考虑k==1 ...
- 三小时学会Kubernetes:容器编排详细指南
三小时学会Kubernetes:容器编排详细指南 如果谁都可以在三个小时内学会Kubernetes,银行为何要为这么简单的东西付一大笔钱? 如果你心存疑虑,我建议你不妨跟着我试一试!在完成本文的学习后 ...
- A1141. PAT Ranking of Institutions
After each PAT, the PAT Center will announce the ranking of institutions based on their students' pe ...
- 树结构关系的数据导出为excel
该文针对的是关于树结构的数据的导出,每一个节点都可以创建不定数的子节点,在选择好某个节点进行导出 时,会把该节点以及子节点的数据都导出来.导出后的excel的格式大概如下图的形式,这个是一个比较理想 ...
- XTest
腾讯优测是一个移动云测试平台,为应用.游戏.H5混合应用的研发团队提供产品质量检测与问题解决服务. 这是腾讯内部针对微信内的H5,做了一套专门的UI自动化框架.而且都是用真机来跑这些框架,在真机上模拟 ...
- 用popart构建常染色体单倍型网络(Autosomal haplotypes network construction with popart)
1)将vcf转化为plink格式,假定输入的vcf文件名为:17893893-17898893.vcf,也可以参考链接:将vcf文件转化为plink格式并且保持phasing状态 /vcftools ...
- linux:提取匹配含有小数点的数字(grep函数)
学艺不精,一开始用了 “grep -ne '46.5743' file.txt” 提取含有46.5743的小数不成功,后面查资料才知道正则表达式中,小数点代表的是:一定有一个任意字节. 正确的写法应该 ...
- 千人基因组(1000 Genomes)提取群体(population)或者样本(sample ID)信息
进入链接:http://www.internationalgenome.org/data-portal/sample 点击“filter by population”,在弹出的选择框里,选择想要下载的 ...
- PHP生成四角图片
<?php /** 圆角 $radius = 100; $img = imagecreatetruecolor($radius, $radius); // 创建一个正方形的图像 $bgcolor ...