浅谈String、StringBuffer和StringBuilder之间的区别
作者:浪浪山的猿
一. String
String 类是不可变类,即一旦一个String对象被创建以后,包含在这个对象中的字符序列是不可改变的,直至这个对象被销毁。
String的实例化方式
通过字面量方式实例化
String str ="abc";
通过new+构造器的方式实例化
String str = newString("abc");
区别:
- 通过字面量方式为字符串赋值时,此时的字符串存储在方法区的字符串常量池中;
- 通过new+构造器方式实例化字符串时,字符串对象存储在堆中,但是字符串的值仍然存储在方法区的常量池中。
String字符串具有不可变性,当字符串重新赋值时,不管是对字符串进行拼接,还是调用String的replace()方法修改指定的字符或字符串,都不会在原来的内存地址进行修改,而是重新分配新的内存地址进行赋值
二. StringBuffer
StringBuffer对象代表一个字符序列可变的字符串,当一个StringBuffer被创建以后,通StringBuffer提供的append()、insert()、reverse()、setCharAt()、setLength()等方法可以改变这个字符串对象的字符序列,但都不会产生新的对象。通过StringBuffer生成的字符串,可以调用toString()方法将其转换为一个String对象。
StringBuffer是线程安全的
StringBuffer类中实现的方法,StringBuffer是如何实现线程安全的呢?
@Override public synchronized int length() { return count; } @Override public synchronized int capacity() { return value.length; } @Override public synchronized void ensureCapacity(int minimumCapacity) { super.ensureCapacity(minimumCapacity); } /** * @since 1.5 */ @Override public synchronized void trimToSize() { super.trimToSize(); }
从源码中可以看到,StringBuffer类中的方法都添加了synchronized关键字,也就是给这个方法添加了一个锁,用来保证线程安全。
三. StringBuilder
StringBuilder类也代表可变字符串对象。实际上,StringBuilder和StringBuffer基本相似,他们的原理与操作一样,两个类的构造器和方法也基本相同。
不同的是:StringBuffer是线程安全的,而StringBuilder则没有实现线程安全功能,所以性能略高。
四. 总结
String、StringBuffer和StringBuilder三者的异同?
- String :不可变的字符序列;底层使用 byte[] 存储。
- StringBuffer :可变的字符序列;线程安全的,效率低;底层使用 byte[] 存储。
- StringBuilder :可变的字符序列;jdk5.0新增的,线程不安全的,效率高;底层使用 byte[] 存储。
从代码角度验证三者的效率对比
接下我们来测试下拼接10000条数据的各自所耗的时间
package com.scg.springcloudordercenter.controller; /** * @author gf * @date 2023/2/21 */ public class StringTest { public static void main(String[] args) { long startTime; long endTime; String str1 = ""; StringBuffer str2 = new StringBuffer(""); StringBuilder str3 = new StringBuilder(""); // 1.拼接str1,计算String所耗时间 startTime = System.currentTimeMillis(); for(int i= 1;i<=10000;i++){ str1 += i; } endTime = System.currentTimeMillis(); System.out.println("String所耗时间为:" + (endTime-startTime) + "毫秒"); // 2.拼接str2,计算StringBuffer所耗时间 startTime = System.currentTimeMillis(); for(int i= 1;i<=10000;i++){ str2.append(i); } endTime = System.currentTimeMillis(); System.out.println("StringBuffer所耗时间为:" + (endTime-startTime) + "毫秒"); // 3.拼接str3,计算StringBuilder所耗时间 startTime = System.currentTimeMillis(); for(int i= 1;i<=10000;i++){ str3.append(i); } endTime = System.currentTimeMillis(); System.out.println("StringBuilder所耗时间为:" + (endTime-startTime) + "毫秒"); } }
结果:
String所耗时间为:745毫秒
StringBuffer所耗时间为:4毫秒
StringBuilder所耗时间为:1毫秒
Process finished with exit code 0
很明显,我们拼接一万次字符串操作就可以对比出三者的效率:StringBuilder>StringBuffer>String
到此这篇关于浅谈String、StringBuffer和StringBuilder之间的区别的文章就介绍到这了,更多相关String、StringBuffer和StringBuilder区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!