java stringbu_Java StringBuffer 和StringBuilder

其实在上面的文章中我已经阐述过了什么是String,其实,String三姐妹中还有两个非常丰满的存在:StringBuffer老大姐和StringBuilder小妹妹.

首先,前面我们说过String是不能被修改的,无论你如何对String进行赋值(+)都会在字符串常连池里面生成一个值.并且把这个值得地址引用给String变量,所以,只要是玩String后面添加东西,都是创建一个全新的JavaString对象.这样,我们可以来做个实验:

//本来

一开始是想计算五百次的String添加计算的,kanla9ishi天真了,那么五万次呢....

class StringTest {

public static void main(String[] args) {

//在这里定义一个循环结构,循环五百万次.我们开你一下耗时:

long start = System.currentTimeMillis();

int x = 50000;

String value = "";

for (int i = 0; i < x; i++) {

value += i;

}

long stop = System.currentTimeMillis();

System.out.println("String 总共耗时为: " + (stop - start)/1000+"秒");

}

}

输出:

String 总共耗时为: 6秒

现在来看StringBUffderder的情况:注意时间单位

class StringBufferTest2{

public static void main(String[] args) {

long start = System.currentTimeMillis();

int w = 5000000;

StringBuffer stringBuffer = new StringBuffer();

for(int i = 0;i

stringBuffer.append(i);

}

long stop = System.currentTimeMillis();

System.out.println("StringBuffer 总共耗时为: " + (stop - start)+"毫秒");

}

}

输出:

StringBuffer 总共耗时为: 308毫秒

然后...

class StringBudilerTest2{

public static void main(String[] args) {

long start = System.currentTimeMillis();

int y = 5000000;

StringBuilder stringBuilder = new StringBuilder();

for(int i = 0;i

stringBuilder.append(i);

}

long stop = System.currentTimeMillis();

System.out.println("StringBudiler: 总共耗时为: " + (stop - start)+"毫秒");

}

}

输出:

.StringBudiler: 总共耗时为: 240毫秒

大家可以很明显的看出来了是怎么一回事.String循环五万次,了6000毫秒,而Stringbuffer循环添加五百万个只用了300毫秒!!!当然Stringbuilder只用了200毫秒.我的天,这是什么情况?

其实,为什么String三姐妹这件的差距这么的,就在于我开篇所说的,对于String来说,没错往已有的字符串后面追加内容,都是一个新的对对象,是对象就需要去给他开辟内存等等一些列复杂的炒作,但是,记住,但是@@@Stringbuffer和Stringbudiler在已有的字符串后面追加,其实是在修应该这个已经存在了的String对象,而没有创建新的对象!这既是为什么有这么大差距的原因了..是的,就是这样的....

那么...下一个问题.为什么会有两个高速修改字符类型的类?Stringbuffer和StringBudiler?

其实从上面的数据也可以看出一点,Stringbuffer的速度没有StrinhBuilder的速度快的,这是因为,StringBuffer是一个线程安全的类,你可以从他的源代码看到他的所有方法第都添加了synchronized关键字来保证线程安全.而StringBuild没有这种限制.如何选择就得看你的业务觉得了.

最后一个问题.Stringbuffer和StringBudiler还有提升速度的空间吗?

答案是有的.通过分析源代码我们可以看到一个非常现实的东西,那就是,Sb们都有一个初始的容量.其值为16

class StringBufferAndStringBufiler{

public static void main(String[] args) {

StringBuffer stringBuffer = new StringBuffer();

int capacity = stringBuffer.capacity();

System.out.println("stringBuffer的初始容量: " + capacity);

StringBuilder stringBuilder = new StringBuilder();

int capacity1 = stringBuffer.capacity();

System.out.println("stringBuilder的初始容量: " + capacity1);

}

}

输出:

stringBuffer的初始容量: 16

stringBuilder的初始容量: 16

容量是什么?容量就是这个sb能装多少的内容!这枚理解没毛病的

class StringBufferAndStringBufiler{

public static void main(String[] args) {

StringBuffer stringBuffer = new StringBuffer("123");

int capacity = stringBuffer.capacity();

System.out.println("stringBuffer的现有容量: " + capacity);

StringBuilder stringBuilder = new StringBuilder("123");

int capacity1 = stringBuffer.capacity();

System.out.println("stringBuilder的现有容量: " + capacity1);

}

}

输出:

stringBuffer的现有容量: 19

stringBuilder的现有容量: 19

以此可以看出,容量是可以改变的,那么他是在什么时候去改变你的呢?

看源代码:

添加long新类型时:

public AbstractStringBuilder append(long l) {

if (l == Long.MIN_VALUE) {

append("-9223372036854775808");

return this;

}

int appendedLength = (l < 0) ? Long.stringSize(-l) + 1

: Long.stringSize(l);

int spaceNeeded = count + appendedLength;

ensureCapacityInternal(spaceNeeded);

Long.getChars(l, spaceNeeded, value);

count = spaceNeeded;

return this;

}

加```

inr类型时:

public AbstractStringBuilder append(int i) {

if (i == Integer.MIN_VALUE) {

append("-2147483648");

return this;

}

int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1

: Integer.stringSize(i);

int spaceNeeded = count + appendedLength;

ensureCapacityInternal(spaceNeeded);

Integer.getChars(i, spaceNeeded, value);

count = spaceNeeded;

return this;

}

从中都可以看到一个ensureCapacityInternal方法,该方法就是在检查当前容量是否够用.如果不够则扩容.

了解这个对速度的提升有什么帮助呢?

我们可以让他不去做扩容,那么相对的时间就可以减少了.这就要求我闷在初始化sb的时候要给一个大约的初始容量.比如:

class StringBufferTest2{

public static void main(String[] args) {

long start = System.currentTimeMillis();

int w = 5000000;

StringBuffer stringBuffer = new StringBuffer(1000000);//初始化stringBuffer的容量

for(int i = 0;i

stringBuffer.append(i);

}

long stop = System.currentTimeMillis();

System.out.println("StringBuffer 总共耗时为: " + (stop - start)+"毫秒");

}

}

class StringBudilerTest2{

public static void main(String[] args) {

long start = System.currentTimeMillis();

int y = 5000000;

StringBuilder stringBuilder = new StringBuilder(10000000);//初始化stringBuilder的容量

for(int i = 0;i

stringBuilder.append(i);

}

long stop = System.currentTimeMillis();

System.out.println("StringBudiler: 总共耗时为: " + (stop - start)+"毫秒");

}

}

对于这个值到底该是多少 ,当然就得靠你去估计一下咯.

至于sb们的一些方法,大家可以去看一下API其实和String没有多少区别的.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值