• String和StringBuilder效率不同的原理


    在做实验的时候,中间有一个任务为一个图的toString.,用来打印每条边每个点的信息。

    其中用到了字符串的链接 我当时用的是String 的 “+”操作,

    但是图怎么也无法输出,因为有三十多万条边,在大量的字符串的拼接的时候,“+”特别耗时间和内存。

    然后我通过网上查找,选择用StringBuilder的方法解决了这个问题。

    StringBuilder str = new StringBuilder();
    str.append("lalalallal");
    for(int i=0;i<5;i++)
        str.append("lalalallal");
    System.out.println(str);

    但是当时也没有仔细想原理是什么,而后来复习到mutable(可变数据类型)和immutable(不可变数据类型)的时候才仔细思考了这个问题,String和StringBuilder正好是它们的典型代表。

    String是immutable的变量,一旦被创建,它的值就不能被改变。注意:改变一个变量是将该变量指向另一个值的存储空间,二改变一个变量的值是将该变量当前指向的值的存储空间写入一个新的值。

    通过分析snapshot diagram我们发现,当string "+"的时候,是新建了一个String空间然后将原来变量的指向这个空间。原来的String被废弃只能等待着被垃圾回收。又通过后来学习的垃圾回收的机制我们知道这是非常浪费资源的,当然也有其安全性。

    而StringBuilder则是直接修改,所以执行起来很快。

    其实这只是区别的一部分,因为这种机制的不同还带来了很多很多潜在的bug

    比如:

    List<String> list =new LinkedList<>();
    String s1 = new String("aaa");
    list.add(s1);
    System.out.println(list.contains(s1));//true
    s1=s1.concat("q");
    System.out.println(list.contains(s1));//false

     奇怪的是,把s1加入到list之后,修改了s1,此时s1就不包含在list里面了

    通过snapshot diagram可以看见这种现象的原因。List是直接指向元素所在的空间,当修s1之后,s1的引用改变,此时s1指向的空间也已经改变,不再是从前的s1了。

     

    比如:

    		String s="ab";
    		String t=s;
    		s=s+"c";
    		System.out.println(t);//ab
    

     因为虽然t指向了s,但是s改变之后,t指向的值并没有改变,因为此时s是重新指向了新的区域。

    因此,我们在选择合适的类型的时候,要仔细考虑的有安全、效率、还要多个引用带来的潜在的bug

  • 相关阅读:
    开始核心攻坚
    Features postponed for ASP.NET 2.0 Beta 2
    设计模式的认识
    如果您想要提高开发效率,那么给大家推荐一本书,比较实用
    asp.net 2.0 个性化服务探讨
    对于数据缓存依赖的认识
    ASP.NET 2.0学习(1)——XmlDataSource控件中XPath属性之疑惑
    写作的四个境界
    ASP.NET 2.0 product design changes between Beta 1 and Beta 2(a new message from asp.net forum)
    验证控件的问题
  • 原文地址:https://www.cnblogs.com/blairwaldorf/p/9191339.html
Copyright © 2020-2023  润新知