String,StringBuilder,StringBuffer

  • Java平台提供了两种类型字符串:String(存储) 和 StringBuffer/StringBuilder(操作)字符串(StringBuffer是StringBuilder的前身)
  • StringBuffer 和 StringBuilder 类表示的字符串对象可以直接进行修改。StringBuilder 是 JDK 1.5 中引入的,它和 StringBuffer 的方法完全相同,区别在于它是在单线程环境下使用的,因为它的所有方面都没有被 synchronized 修饰,因此它的效率也比 StringBuffer 略高。
  • 有一个面试题问:有没有哪种情况用 + 做字符串连接比调用 StringBuffer / StringBuilder 对象的 append 方法性能更好?
    如果连接后得到的字符串在静态存储区中是早已存在的,那么用+做字符串连接是优于 StringBuffer / StringBuilder 的 append 方法的。
  • java设计者认为共享带来的高效率呀远远胜过提取字符串和拼接自字符串,也就是说String的优点在于–编译器可以让字符串共享。

String

对象不可变的字符序列,对象是常量,在常量池

为什么String设计成不可变的
  • 为了节约很多heap空间,实现了字符串常量池。内容相同的不同的字符串变量都指向池中的同一个字符串。如果可变,不能实现Stringinterning(对不同的字符串仅仅只保存一个)
  • 线程安全考虑,同一个字符串实例可以被多个线程共享。线程安全。
  • 类加载器要用到字符串,不可变性提供了安全性,以便正确的类被加载。
  • 支持hash映射和缓存,字符串是不可变的,所以在创建的时候hashcode就被缓存了,不需要重新计算。使得字符串适合key-value的key键,字符串的处理速度要快过其他的键对象。这就是HashMap中的键往往使用字符串。

StringBuffer

  • 对象可变的字符序列,对象是变量,作为参数传递的是引用型数据类型,在堆上.线程安全的,效率低.
  • 初始容量为16(不存储任何东西),可利用capacity赋予初始值.
  • 多线程操作字符串缓冲区下操作大量数据
String和StringBuffer作为参数传递图解
public class StringBufferTest {
    public static void main(String[] args) {
        String s1="Hello";
        String s2="World";
        System.out.println("s1= "+s1);
        System.out.println("s2= "+s2);
        change(s1,s2);
        System.out.println("s1= "+s1);
        System.out.println("s2= "+s2);
        System.out.println("--------------------------");
        StringBuffer str1 = new StringBuffer("Hello");
        StringBuffer str2 = new StringBuffer("World");
        System.out.println("str1= "+str1);
        System.out.println("str2= "+str2);
        change(str1,str2);
        System.out.println("str1= "+str1);
        System.out.println("str2= "+str2);
    }
    static void change(StringBuffer str1,StringBuffer str2){
        str1=str2;
        str2=str1.append(str2);
    }
    
    static void change(String str1,String str2){
        str1=str2;
        str2=str1+str2;
    }
}

在这里插入图片描述

在这里插入图片描述

main方法入栈。在栈上有2个引用变量s1,s2,同时在常量池有常量"Hello"和"world",地址分别为0x001和0x002在栈上还有2个引用变量sb1,sb2,同时在堆上有对象"Hello"和"world",地址分别为0x010和0x020change(String,String)方法入栈,方法里也有s1和s2变量,把s2的地址赋值给s1,s1地址变为0x002,然后s2=s1+s2属于字符串拼接,因此在堆中拼接一个"Hello,World"的对象,地址为0x003,并把地址值赋给s2 。但是main方法中的s1和s2地址没有发生变化,因此还是输出’‘Hello’‘以及’‘World’'change(StringBuffer)方法入栈,方法里也有sb1和sb2变量,地址为0x010和0x020,指向堆中的对象。然后把sb2赋值给sb1,sb1=0x020,指向"World"。sb1.append(sb2)等于worldworld。但是main方法中的sb1和sb2没有发生改变,所以还是指向原来的对象,输出"Hello"和"WorldWorld".

StringBuffer和数组的区别
  • StringBuffer和数组都可以看成一个容器
  • StringBuffer可以自动扩容,数组长度固定
  • StringBuffer可以把任意数据类型转换为字符存储,数组只能存储一个数据类型.
StringBuilder
  • 不可变的字符序列,线程不安全,效率高
  • 单线程操作字符串缓冲区下操作大量数据

速度

StringBuilder>StringBuffer>String

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

王不二kkw

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

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

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

打赏作者

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

抵扣说明:

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

余额充值