String、StringBuffer和StringBuilder的区别

不可变字符串类String

字符串的创建有两种方式:

1. String s1 = new String("123456");
2. String s2 = "123456";
s1使用new来新建一个String对象,放在堆中
不管字符串缓冲池中有没有匹配的字符串常量,都会new一个字符串对象。

在这里插入图片描述

s2使用等号来创建一个String对象
首先jvm会查看字符串缓冲池中有没有值"123456"的对象,
如果有,就将这个字符串对象的地址传给s2;
如果没有,将在字符串缓冲池中新建一个字符串对象,将新的对象地址传给s2。

在这里插入图片描述
下面我们来比较两种不同方式建立的字符串,加深一下字符串创建的理解

String s1 = new String("123456");
String s2 = "123456";
if(s1 == s2)
	System.out.println(s1 == s2);
else
	System.out.println(s1 != s2);
输出结果:true
根据两种创建方式,很容易理解这两个字符串变量指向同一个对象的地址,
所以s1和s2完全相等。
那么如果使用new建立两个的字符串,结果必然为false

为什么说String类的字符串不可变?
我们可以查看JDK,很容易发现所有的String类的方法中没有改变字符串值的方法,字符串对象存在堆中,对象的值为字符串常量放在字符串缓冲区中,因为字符串常量不可改变,故字符串不可改变。
举个栗子
在这里插入图片描述

String类中的replace方法也是先将原字符串复制一份,在新的字符串对象中
将指定字符替换

查看String类源码,可以看到String类为 final 类,字符串的值放在final数组value[]中,所以我们把字符串的值叫字符串常量,因为常量不可变。
在这里插入图片描述

可变字符串类StringBuffer和StringBuilder

  StringBuffer和StringBuilder有一个共同点,他们都可以拼接字符串(通过append方法),并能改变字符串的值(有JDK文档就可以看出来)。
  二者的区别在于StringBuffer是多线程,线程安全;StringBuilder是单线程,线程不安全,如果频繁使用字符串拼接,建议使用StringBuilder。
  虽然String可以通过重载运算符来进行字符串拼接,但是这只适合少量的,如果出现大量字符串拼接,还是使用StringBuilder。
拓展一下

StringBuilder字符串拼接和String字符串拼接

String s1 = "hello";
String s2 = "world";
System.out.println(s1+s2);

这时候使用 + 来拼接字符串很方便。
当出现很多字符串时,我们就能看到字符串拼接的不足。
举个栗子

public static void main(String[] args) {
		String s = "oh,";
		String[] ss = new String[] {"he", "llo", "wo", "rl", "d!"};
		for(int i = 0; i < ss.length; i++){
			s += ss[i];
		}
		System.out.println(s);
	}//输出:oh,helloworld!
我们利用javap反编译一下这个循环(javap -c Main)

在这里插入图片描述

在每次循环中我们都会new一个StringBuilder对象,
使用append方法将字符串拼接后使用toString方法转换为字符串给字符串s

既然使用String直接拼接用到了StringBuilder,我们还不如直接新建一个StringBuilder对象。

public static void main(String[] args) {
		String s = "oh,";
		StringBuilder cs = new StringBuilder(s);
		String[] ss = new String[] {"he", "llo", "wo", "rl", "d!"};
		for(int i = 0; i < ss.length; i++){
			cs.append(ss[i]);
		}
		s = cs.toString();
		System.out.println(s);
	}//输出:oh,helloworld!

在这里插入图片描述

很显然,我们发现循环中的代码减少了,那么也提升了拼接的效率
这就是我们要使用StringBuilder拼接的原因。

总结

其实String利用加法拼接字符串是将‘+’和‘+=’重载了,类似于C++中的运算符重载,但是Java中只允许重载这两个运算符,重载就是利用了StringBuilder的append方法,所以,遇到大量的拼接,我们还是要多使用StringBuilder。
String和StringBuffer及StringBuilder的区别同时也是面试题,不光我们要知道原理,还要能举出实例来论证。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呆呆papa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值