String的两种创建方式+StringBuffer+StringBuilder

一:String
直接赋值和使用new的区别

String str = new String();
此时JVM

在这里插入图片描述

Demo_01_String

//直接赋值
String str1 = "hello";
String str2 = "hello";
String str3 = "world";
System.out.println("string==:"+(str1 == str2));//true:二者都指向常量池中同一对象,其地址值相同
System.out.println("string==:"+(str2 == str3));//false
System.out.println("string.equals:"+str1.equals(str2));//true
System.out.println("str1地址:"+str1.hashCode());	//99162322
System.out.println("str2地址:"+str2.hashCode()); //99162322
System.out.println("str3地址:"+str3.hashCode()); //113318802

// new String
String str4 = new String("hello");
String str5 = new String("hello");
String str6 = new String("world");
System.out.println("string==:"+(str1 == str4));//false:存放的地址不同
System.out.println("string==:"+(str4 == str5));//false:比较两个包装类的引用是否指向同一个对象,即在堆中的地址是否相同
System.out.println("string.equals:"+str1.equals(str4));//true 比较引用类型的值是否相等
System.out.println("string.equals:"+str4.equals(str5));//true
System.out.println("str4地址:"+str4.hashCode());	//99162322
System.out.println("str5地址:"+str5.hashCode());	//99162322
System.out.println("str6地址:"+str6.hashCode());	//113318802

//字符串相加
String strConst = str2 + str3;//是先加,然后在常量池找
String strNew = str5 + str6;//先开空间,再拼接
System.out.println(strConst.hashCode());
System.out.println(strNew.hashCode());
System.out.println("字符串相加后比较:"+(strConst == strNew));	//
System.out.println("字符串相加后比较:"+strConst.equals(strNew));

str4和str5对同一个对象的引用

Demo_02_StringBuffer

StringBuffer sbf1 = new StringBuffer("hello");
StringBuffer sbf2 = new StringBuffer("hello");
StringBuffer sbf3 = new StringBuffer("world");
System.out.println("stringBuffer==:"+(sbf1 == sbf2));	//false
System.out.println("stringBuffer.equals:"+sbf1.equals(sbf2));	//false
System.out.println("stringBuffer.equals:"+sbf2.append(sbf3));	//拼接

Demo_03_StringBuilder

StringBuilder sbu1 = new StringBuilder("hello");
StringBuilder sbu2 = new StringBuilder("hello");
StringBuilder sbu3 = new StringBuilder("world");
System.out.println("stringBuilder==:"+(sbu1 == sbu2));	//false
System.out.println("stringBuilder.equals:"+sbu1.equals(sbu2))	//false
System.out.println("stringBuilder.equals:"+sbu2.append(sbu3));
  1. 由于String变量实际上是对一个String对象的引用(指向常量池),所以两个通过new生成的String变量永远是不相等的(因为new生成的是两个对象,其(在堆中的)内存地址不同)。
  2. String是final类,其值是不可变的,看以下板栗,只是改变了赋值地址;
// 1. 重新赋值
String str1 = "hello";
System.out.println("str1原本地址:"+str1.hashCode());	//99162322
str1 = "java";
System.out.println("str1改变后的地址:"+str1.hashCode());	//3254818

重新赋值后str1指向新地址,但旧地址中保存的"world"依旧存在,但已经不再是str1所指向的,str1已经指向了其它地址。
所有对String类型进行改变的时候都会重新生成一个新的String对象,如果字符串的内容经常改变,而且不考虑多线程的话,建议使用StringBuilder

// 2. 字符串拼接后地址有无改变?
	    String strConst = str2 + str3;//是先加,然后在常量池找
		String strNew = str5 + str6;//先开空间,再拼接
		System.out.println("字符串拼接后的地址:"+strConst.hashCode()); //变成-1524582912
		System.out.println("字符串拼接后的地址:"+strNew.hashCode());	//变成-1524582912
		
	    System.out.println("sbf3原本地址:"+sbf3.hashCode());	//27134973
		System.out.println("sbf3拼接后:"+sbf2.append(sbf3));
		System.out.println("sbf3拼接后的地址:"+sbf3.hashCode());	//还是sbf3的地址27134973

查看源码可知String重写了equals()方法,但StringBuffer和StringBuilder没有

看JDK怎么说

StringBuffer

  1. 是线程安全的可变字符序列,可将字符串缓冲区安全地用于多个线程,可以在必要时对这些方法进行同步;
  2. 主要操作是 append 和 insert 方法;
  3. 没有重写equals方法

StringBuilder

  1. 此类提供一个与 StringBuffer 兼容的 API,但不保证同步;
  2. 该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候,这样比buffer快
  3. 主要操作和buffer一样
  4. 没有重写equals方法

总结

  1. String = 操作少量的数据
  2. StringBuilder = 单线程操作字符串缓冲区 下操作大量数据;线程非安全的
  3. StringBuffer = 多线程操作字符串缓冲区 下操作大量数据;线程安全的
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值