好久没有更新博客了,趁着现在复习Java,随便就把Java里面的部分笔记拿出来分享给大家!
首先说明String类型不是基本数据类型,它被定义成类,属于引用数据类型.String是不可变的对象,因此在每次对String类型进行改变的时候都会生成一个新的String对象,然后将指针指向新的String对象,
比如:String str = “my”; //假设str指向地址0x0001
str = “name”; //重新赋值后str指向0x0002
但0x0001地址中保存的”my”仍然存在,但已经不再是str所指向的,因为String的操作都是改变赋值地址而不是改变值操作。所以在要经常改变其内容的字符串最好不要用String,因为每次生成对象都会对系统的性能产生影响,特别当内存中无引用的对象多了后,JVM的GC就会开始工作,那速度也是相当慢的。
再比如:
String s2 = “hello”
s2 += “world”;
这操作是:先创建一个String对象,在接下来进行字符串连接的时候,有创建了一个StringBuilder(jdk1.5前是StringBuffer),然后调用append()方法,最后调用toString()方法。
但是使用Stringbuffer结果就不一样了,每次操作都会对StringBuffer对象本身进行操作,而不是生成新的对象,再改变对象的引用。所以在一般情况下我们推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。而在某些特别情况下, String 对象的字符串拼接其实是被 JVM 解释成了 StringBuffer 对象的拼接,所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,而特别是以下的字符串对象生成中, String 效率是远要比 StringBuffer 快的:
String S1 = “This is only a” + “ simple” + “ test”;
StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);
你会很惊讶的发现,生成 String S1 对象的速度简直太快了,而这个时候 StringBuffer 居然速度上根本一点都不占优势。其实在 JVM 眼里,这个
String S1 = “This is only a” + “ simple” + “test”; 就是: String S1 = “This is only a simple test”; 所以当然不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的 String 对象的话,速度就没那么快了,譬如:
String S2 = “This is only a”;
String S3 = “ simple”;
String S4 = “ test”;
String S1 = S2 +S3 + S4;
这时候 JVM 会规规矩矩的按照原来的方式去做, S1 对象的生成速度就不像刚才那么快了。
由此我们得到第一步结论: 在大部分情况下 StringBuffer > String
那么StringBuilder 呢?StringBuilder 是 JDK5.0 中新增加的一个类,它跟 StringBuffer 的区别看下面的介绍。
StringBuffer 线程安全的可变字符序列。类似于 String 的字符串缓冲区,但不能修改。可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发 生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。
每个字符串缓冲区都有一定的容量。只要字符串缓冲区所包含的字符序列的长度没有超出此容量,就无需分配新的内部缓冲区数组。如果内部缓冲区溢出,则此容量 自动增大。从 JDK 5.0 开始,为该类增添了一个单个线程使用的等价类,即 StringBuilder 。与该类相比,通常应该优先使用 StringBuilder 类,因为它支持所有相同的操作,但由于它不执行同步,所以速度更快。
但是如果将 StringBuilder 的实例用于多个线程是不安全的。需要这样的同步,则建议使用 StringBuffer 。
这样说估计大家都能明白他们之间的区别了,那么下面我们再做一个一般性推导:
在大部分情况下 StringBuilder > StringBuffer
所以大部分情况下,运行效率 StringBuilder > StringBuffer > String,当然特殊情况特殊考虑!
除非注明,饮水思源博客文章均为原创,转载请以链接形式标明本文地址