zoukankan      html  css  js  c++  java
  • Java中String、StringBuffer、StringBuilder区别与理解

    一、先比较String、StringBuffer、StringBuilder变量的HashCode值

    使用System.out.println(obj.hashcode())输出的时对象的哈希码,
    而非内存地址。在Java中是不可能得到对象真正的内存地址的,因为Java中堆是由JVM管理的不能直接操作。
    只能说此时打印出的Hash码表示了该对象在JAVA虚拟机中的内存位置,
    Java虚拟机会根据该hash码最终在真正的的堆空间中给该对象分配一个地址.
    但是该地址 是不能通过java提供的api获取的

    String变量连接新字符串会改变hashCode值,变量是在JVM中“连接——断开”;
    StringBuffer变量连接新字符串不会改变hashCode值,因为变量的堆地址不变。
    StringBuilder变量连接新字符串不会改变hashCode值,因为变量的堆地址不变。

    小结:哈希码相同的变量,其内容不一定相同;内容向同变量,哈希码不一定相同;

    public class Buffer_HashCode01 {
    public static void main(String[] args) {
        String str1="学海无涯苦作舟";
        System.out.println("String 的 str1的hascode"+str1.hashCode());
        str1=str1+"人间正道是沧桑";      //注意此str1的存储地址已发生变化
         System.out.println("String 的 str1的hascode"+str1.hashCode());
        System.out.println(str1);
        StringBuffer sb1=new StringBuffer("弟子规");
          System.out.println("原来               StringBuffer 的 hascode:"+sb1.hashCode());
        StringBuffer sb2=sb1.append("圣人教");    //注意sb1和sb2指向同一个地址
           System.out.println("添加字符串后StringBuffer 的 hascode:"+sb2.hashCode());
        sb2.insert(6,"海纳百川");
        StringBuilder sb=new StringBuilder("这显然是上半年");
        System.out.println("改变前StringBuilder变量的hashCode值"+sb.hashCode());
        sb.append("哦是的啊");
        System.out.println("改变后StringBuilder变量的hashCode值"+sb.hashCode());
        
    }
    }

    结果:

    String 的 str1的hascode-2054942391
    String 的 str1的hascode895667206
    学海无涯苦作舟人间正道是沧桑
    原来 StringBuffer 的 hascode:1311053135
    添加字符串后StringBuffer 的 hascode:1311053135
    改变前StringBuilder变量的hashCode值118352462
    改变后StringBuilder变量的hashCode值118352462

    二、比较String、StringBuffer、StringBuilder性能(仅在繁复操作)

    String类由于Java中的共享设计,在修改变量值时使其反复改变栈中的对于堆的引用地址,所以性能低。

    StringBuffer和StringBuilder类设计时改变其值,其堆内存的地址不变,避免了反复修改栈引用的地址,其性能高。

    其中StringBuilder是专门类似于StringBuffer类的非线性安全类,即StringBuffer是线性安全的,适合于多线程操作;

    StringBuilder是线性不安全的,适合于单线程操作,其性能比StringBuffer略高。

    public class Xing_Neng_SSS01 {
    public static void main(String[] args) {
        long begin1 = System.currentTimeMillis();
        String str = "";
         for(int i=0;i<10000;i++){
              str = str+i;
         }
         long end1 = System.currentTimeMillis();
         long time1 = end1 - begin1;
         System.out.println("1、String + time="+time1);
         
         long begin2 = System.currentTimeMillis();
         String str2 = "";
          for(int i=0;i<10000;i++){
               str2 = str2.concat(i+"");
          }
          long end2 = System.currentTimeMillis();
          long time2 = end2 - begin2;
          System.out.println("2、String concat time="+time2);
          
          long begin3 = System.currentTimeMillis();
          StringBuffer str3 = new StringBuffer();
           for(int i=0;i<10000;i++){
                str3.append(""+i);
           }
           long end3 = System.currentTimeMillis();
           long time3 = end3 - begin3;
           System.out.println("3、StringBuffer time="+time3);
           
           long begin4 = System.currentTimeMillis();
           StringBuilder str4 = new StringBuilder();
            for(int i=0;i<10000;i++){
                 str4.append(""+i);
            }
            long end4 = System.currentTimeMillis();
            long time4 = end4 - begin4;
            System.out.println("4、StringBuilder time="+time4);
    }
    }

    结果:

    1、String + time=241
    2、String concat time=92
    3、StringBuffer time=4
    4、StringBuilder time=2

    三、String共享设计

    当String使用引号创建字符串时,会先去字符串池中找,找到了就返回,找不到就在字符串池中增加一个然后返回,这样由于共享提高了性能。

     而new String()无论内容是否已经存在,都会开辟新的堆空间,栈中的堆内存也会改变。

    下面是==来比较地址是否相等。

    public class String_Equals01 {
    public static void main(String[] args) {
        String str1="学海无涯苦作舟人间正道是沧桑";
        String str11=str1;
        String str12="学海无涯苦作舟人间正道是沧桑";
        String str13=new String("学海无涯苦作舟人间正道是沧桑");
       
         System.out.println("String 的 str1 的hascode"+str1.hashCode());
         System.out.println("String 的 str11的hascode"+str11.hashCode());
         System.out.println("String 的 str12的hascode"+str12.hashCode());
         System.out.println("String 的 str13的hascode"+str13.hashCode());
         System.out.println("str1==str11  "+(str1==str11));
         System.out.println("str1==str12  "+(str1==str12));
         System.out.println("str1==str13  "+(str1==str13));
    }
    }

    结果:

    String 的 str1 的hascode895667206
    String 的 str11的hascode895667206
    String 的 str12的hascode895667206
    String 的 str13的hascode895667206
    str1==str11 true
    str1==str12 true
    str1==str13 false

  • 相关阅读:
    记一次性能优化经历
    把一个一中的字段更新另一个表中的t-sql
    Dapper 中使用sql in 关键字查询
    HTML5 学习笔记 应用程序缓存
    HTML5学习笔记 Web存储
    HTML5 学习笔记 表单属性
    HTML5学习笔记 Geolocation(地理定位)
    vim插件之delimitMate.vim
    vim 插件之 surround.vim
    vim 脚本之快速打印log
  • 原文地址:https://www.cnblogs.com/duange/p/6136782.html
Copyright © 2011-2022 走看看