String与StringBuffer,StringBuilder的区别

这三个类之间的区别主要是在两个方面,即运行速度和线程安全这两方面。

1.运行速度

String < StringBuffer < StringBuilder

首先String为字符串常量,一旦创建之后该对象不可更改;StringBuilder和StringBuffer均为字符串变量,可以更改。

String实现原理:

我们创建的String对象中的字符串是通过private final char value[] 存储的,也就是说String对象创建后就不能修改对象中存储的内容,所以说String类是不可变的。

字符串是我们平时经常使用的,频繁的读写操作消耗了大量的时间和内存空间。所以JVM为了提高性能和减少时间空间开销,在内存中开辟了一段空间作为字符串常量池

每当我们创建一个字符串常量时,JVM会先去字符串常量池检查是否已经存在,如果这个字符串已经存在,就直接返回这个已存在字符串的地址;如果不存在,就在字符串常量池中创建这个字符串并返回其地址。所以在字符串常量池中不会存在两个相同的字符串。

字符串常量String实例区别:

字符串常量是存储在字符串常量池中的,而String实例是存储在内存堆上的。也就是说,以下代码会创建两个对象(在栈区创建变量str,在堆区创建String类的实例):

String str = new String("123");

这里写图片描述

String执行效率低的原因:

我们平时在使用String字符串时,经常会对其进行更改,比如如下代码:

String str = "";
for(int i = 0;i < 1000; i++){
    str += i;
}
//实际上,第i次执行过程如下:
StringBuilder temp = new StringBuilder(); 
temp.append(str); 
temp.append(i); 
String str = temp.toString();

在循环体里面,每次拼接都会生成一个StringBuilder的临时对象temp,那么这个程序片段执行下去就会产生1000个StringBuilder的临时对象。

可见,Java中对String对象进行的操作实际上是一个不断创建新的对象并且将旧的对象回收的一个过程,所以执行速度很慢。

而StringBuffer和StringBuilder是字符串变量,直接对变量进行修改,不需要不断创建新的对象和回收,执行速度快于String。

2.线程安全

StringBuffer是线程安全的,而StringBuilder不是线程安全的,因此StringBuffer的执行速度会慢于StringBuilder。

StringBuffer中很多方法带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。

使用场景:

String:适用于少量的字符串操作的情况;

StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况;

StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况。

猜你喜欢

转载自blog.csdn.net/j1231230/article/details/78561441