String和StringBuilder效率不同的原理

在做实验的时候,中间有一个任务为一个图的toString.,用来打印每条边每个点的信息。
其中用到了字符串的链接 我当时用的是String 的 “+”操作,
但是图怎么也无法输出,因为有三十多万条边,在大量的字符串的拼接的时候,“+”特别耗时间和内存。
然后我通过网上查找,选择用StringBuilder的方法解决了这个问题。

1 StringBuilder str = new StringBuilder();
2 str.append(“lalalallal”);
3 for(int i=0;i<5;i++)
4 str.append(“lalalallal”);
5 System.out.println(str);

但是当时也没有仔细想原理是什么,而后来复习到mutable(可变数据类型)和immutable(不可变数据类型)的时候才仔细思考了这个问题,String和StringBuilder正好是它们的典型代表。
String是immutable的变量,一旦被创建,它的值就不能被改变。注意:改变一个变量是将该变量指向另一个值的存储空间,二改变一个变量的值是将该变量当前指向的值的存储空间写入一个新的值。
通过分析snapshot diagram我们发现,当string "+"的时候,是新建了一个String空间然后将原来变量的指向这个空间。原来的String被废弃只能等待着被垃圾回收。又通过后来学习的垃圾回收的机制我们知道这是非常浪费资源的,当然也有其安全性。

在这里插入图片描述
而StringBuilder则是直接修改,所以执行起来很快。
在这里插入图片描述
其实这只是区别的一部分,因为这种机制的不同还带来了很多很多潜在的bug

比如:
1 List list =new LinkedList<>();
2 String s1 = new String(“aaa”);
3 list.add(s1);
4 System.out.println(list.contains(s1));//true
5 s1=s1.concat(“q”);
6 System.out.println(list.contains(s1));//false

 奇怪的是,把s1加入到list之后,修改了s1,此时s1就不包含在list里面了
 
通过snapshot diagram可以看见这种现象的原因。List是直接指向元素所在的空间,当修s1之后,s1的引用改变,此时s1指向的空间也已经改变,不再是从前的s1了。
 在这里插入图片描述
比如:

1 String s=“ab”;
2 String t=s;
3 s=s+“c”;
4 System.out.println(t);//ab

因为虽然t指向了s,但是s改变之后,t指向的值并没有改变,因为此时s是重新指向了新的区域。
在这里插入图片描述
因此,我们在选择合适的类型的时候,要仔细考虑的有安全、效率、还要多个引用带来的潜在的bug

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值