JavaSE【 String 类】(2)(

一、字符串的不可变性

1.String本身不可变

字符串修改
注意:尽量避免直接对 String 类型对象进行修改,因为 String 类是不能修改的,所有的修改都会创建新对象,效率 非常低下。
public static void main(String[] args) {
        /**
         * String 本身是不可修改的
         * 下面代码,创建了三个对象 "hello" "abc" "helloabc"
         * 查看源码  private final char value[];
         * 发现 如果想要改变str 那么就需要拿到 value[]这个值,但是这个值被 private 所修饰
         * 所以在 String类 外部,无法拿到或者修改这个 value值
         */
        String str = "hello";
        System.out.println(str);//hello
        str += "abc";
        System.out.println(str);//helloabc
        /**
         * 但是从运行结果上来看,好像的确 变成了 helloabc
         * 打开cmd 查看 java汇编码
         */
    }

String 类中的字符实际保存在内部维护的 value 字符数组中 ,该图还可以看出:

1. String类被final修饰,表明该类不能被继承

2. value被修饰被final修饰,表明value自身的值不能改变,即不能引用其它字符数组,但是其引用空间中 的内容可以修改。

3.value被修饰被privatel修饰,如果想要改变str 那么就需要拿到 value这个值,但是这个值被 private 所修饰 所以在 String类 外部,无法拿到或者修改这个 value值。

 

2.Stringbuilder

根据汇编码,发现String在拼接字符串的时候创建了StringBuilder这个对象

用StringBuilder模拟实现

发现能实现同样的效果 helloabc 

public static void main2(String[] args) {
        /**
         * StringBuilder
         * 根据上面main1代码的汇编代码,模拟以下代码
         */
        String str = "hello";
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(str);
        stringBuilder.append("abc");

        str = stringBuilder.toString();
        System.out.println(str);//helloabc
    }

二、比较String 、StringBuffer、StringBuilder

 public static void main(String[] args) {
        /**
         * 对比String 、StringBuffer、StringBuilder
         *
         */
        //String
        long start = System.currentTimeMillis();//执行开始时间
        String string = "";
        for(int i = 0; i < 10000; ++i){
            string += i; //在空字符串后,循环拼接10000次字符
        }
        long end = System.currentTimeMillis();//执行结束时间
        System.out.println("String前后执行的时间:"+(end - start));

        //StringBuffer
        start = System.currentTimeMillis();
        StringBuffer stringBuffer = new StringBuffer("");
        for(int i = 0; i < 10000; ++i){
            stringBuffer.append(i);
        }
        end = System.currentTimeMillis();
        System.out.println("stringBuffer前后执行的时间:"+(end - start));


        //StringBuilder
        start = System.currentTimeMillis();
        StringBuilder stringBuilder = new StringBuilder();
        for(int i = 0; i < 10000; ++i){
            stringBuilder.append(i);
        }
        end = System.currentTimeMillis();
        System.out.println("stringBuilder前后执行的时间:"+(end - start));

    }

发现

String拼接字符串时,耗费的时间最长。

StringBuffer和StringBuilder 两者耗费时间相差不大,都是极短的。

String 与 StringBuffer、StringBuilder最大的区别就在于 StringBuffer、StringBuilder调用了append函数。

查看append 底层代码逻辑

返回的是this

查看汇编比较

1.String 在循环拼接字符串内时,每一次循环都 new了一个StringBuilder对象

 

2.StringBuffer 每次循环不会new新的对象,直接返回 stringBuffer 的值

 

3.StringBuilder 也没有在每次循环中创建新的对象

 1)对比String 和 StringBuffer、StringBuilder

String 不可变, StringBuffer、StringBuilder可变

String每次循环都在创建对象、 拼接对象、 销毁对象,无形之中消耗了大量时间

而StringBuffer、StringBuilder 直接在该字符串的位置后拼接对象,返回的这个字符串的地址

耗费时间自然就少了许多

  2)对比StringBuffer 和 StringBuilder

StringBuffer 的append方法 被synchronized所修饰了,这个保证了线程安全,而StringBuilder 没有线程安全

StringBuffer 里所有的方法都被synchronized修饰,都保证了线程安全。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值