1 String
String:字符串常量,字符串长度不可变。
2 StringBuffer
StringBuffer:字符串变量(Synchronized,即线程安全)。如果要频繁对字符串内容进行修改,出于效率考虑最好使用StringBuffer,如果想转成String类型,可以调用StringBuffer的toString()方法。
Java.lang.StringBuffer线程安全的可变字符序列。在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。可将字符串缓冲区安全地用于多个线程。
StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将?定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。例如,如果 z 引用一个当前内容是“start”的字符串缓冲区对象,则此方法调用 z.append("le") 会使字符串缓冲区包含“startle”,而 z.insert(4, "le") 将更改字符串缓冲区,使之包含“starlet”。
3 StringBuilder
StringBuilder:字符串变量(非线程安全)。
java.lang.StringBuilder是一个可变的字符序列,是JDK5.0新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因?在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。
在大部分情况下,StringBuilder > StringBuffer。
4 三者区别
String 类型和StringBuffer的主要性能区别:String是不可变的对象, 因此在每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因?每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,性能就会降低。
使用 StringBuffer 类时,每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。所以多数情况下推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。
在某些特别情况下, String 对象的字符串拼接其实是被 JVM 解释成了 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”;
JVM直接把上述语句当作:
String S1 = “This is only a simple test”;
所以速度很快。但要注意的是,如果拼接的字符串来自另外的String对象的话,JVM就不会自动转换了,速度也就没那么快了,例如:
String S2 = “This is only a”; String S3 = “ simple”; String S4 = “ test”; String S1 = S2 +S3 + S4;
这时候,JVM 会规规矩矩的按照原来的方式去做。
在大部分情况下,StringBuffer > String。
4.StringBuffer和StringBuilder
二者几乎没什么区别,基本都是在调用父类的各个方法,一个重要的区别就是StringBuffer是线程安全的,内部的大多数方法前面都有关键字synchronized,这样就会有一定的性能消耗,StringBuilder是非线程安全的,所以效率要高些。
public static void main(String[] args) throws Exception { String string = "0"; int n = 10000; long begin = System.currentTimeMillis(); for (int i = 1; i < n; i++) { string += i; } long end = System.currentTimeMillis(); long between = end - begin; System.out.println("使用String类耗时:" + between+"ms"); int n1 = 10000; StringBuffer sb = new StringBuffer("0"); long begin1 = System.currentTimeMillis(); for (int j = 1; j < n1; j++) { sb.append(j); } long end1 = System.currentTimeMillis(); long between1 = end1 - begin1; System.out.println("使用StringBuffer类耗时:" + between1+"ms"); int n2 = 10000; StringBuilder sb2 = new StringBuilder("0"); long begin2 = System.currentTimeMillis(); for (int k = 1; k < n2; k++) { sb2.append(k); } long end2 = System.currentTimeMillis(); long between2 = end2 - begin2; System.out.println("使用StringBuilder类耗时:" + between2+"ms"); }
输出:
使用String类耗时:982ms 使用StringBuffer类耗时:2ms 使用StringBuilder类耗时:1ms
虽然这个数字每次执行都不一样,而且每个机子的情况也不一样,但是有几点是确定的,String类消耗的明显比另外两个多得多。还有一点就是,StringBuffer要比StringBuilder消耗的多,尽管相差不明显。
5 使用策略
(1)基本原则:如果要操作少量的数据,用String ;单线程操作大量数据,用StringBuilder ;多线程操作大量数据,用StringBuffer。
(2)不要使用String类的"+"来进行频繁的拼接,因?那?的性能极差的,应该使用StringBuffer或StringBuilder类,这在Java的优化上是一条比较重要的原则。举个例子:在使用String 的时候,拼接字符串时使用“+”在JVM上形成临时的StringBuffer对象,同时在每一个字符串上都建立一个对象,拼接了两个字符串一共需要创建4个对象!(一个保存结果的String,两个字符串对象,一个临时的StringBuffer对象)。而使用StringBuffer的话,只需创建2个对象!一个StringBuffer对象和保存最后结果的的String对象 。
(3)?了获得更好的性能,在构造 StirngBuffer 或 StirngBuilder 时应尽可能指定它们的容量。当然,如果你操作的字符串长度不超过 16 个字符就不用了。不指定容量会显著降低性能。
(4)StringBuilder一般使用在方法内部来完成类似"+"功能,因?是线程不安全的,所以用完以后可以丢弃。StringBuffer主要用在全局变量中。
(5)相同情况下使用 StirngBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。而在现实的模块化编程中,负责某一模块的程序员不一定能清晰地判断该模块是否会放入多线程的环境中运行,因此:除非确定系统的瓶颈是在 StringBuffer 上,并且确定你的模块不会运行在多线程模式下,才可以采用StringBuilder;否则还是用StringBuffer。
问题内容: 使用此代码: 当我使用StringBuilder运行代码时,出现错误消息 尝试了StringBuffer,它可以工作。StringBuffer对象的内容被编译为“ Java和Eclipse ..”。 } 问题答案: 确实 有一个接受a 作为参数 的构造函数,并且 确实 有一个方法(由于实现了它必须实现)。 结论:这是您的IDE中的一个不幸,它没有导入正确的。您使用的另一个库具有不幸的“
问题内容: 我正在阅读“ 更好,更快,更轻便的Java ”(作者Bruce Tate和Justin Gehtland),并且熟悉敏捷类型团队的可读性要求,例如Robert Martin在其干净的编码书中讨论的内容。在我现在所在的团队中,已明确告知我不要使用运算符,因为它会在运行时创建额外的(和不必要的)字符串对象。 但是,这篇写于‘04的文章讨论了对象分配如何与10条机器指令相关。(基本上免费)
主要内容:总结在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串。String 类是不可变类,即一旦一个 String 对象被创建以后,包含在这个对象中的字符序列是不可改变的,直至这个对象被销毁。 Java 提供了两个可变字符串类 StringBuffer 和 StringBuilder,中文翻译为“字符串缓冲区”。 StringBuilder 类是 JDK 1.5 新增的类,
本文向大家介绍JDK源码分析之String、StringBuilder和StringBuffer,包括了JDK源码分析之String、StringBuilder和StringBuffer的使用技巧和注意事项,需要的朋友参考一下 前言 本文主要介绍了关于JDK源码分析之String、StringBuilder和StringBuffer的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细
本文向大家介绍JAVA中String类与StringBuffer类的区别,包括了JAVA中String类与StringBuffer类的区别的使用技巧和注意事项,需要的朋友参考一下 在Java中有两种字符串的操作:String类和StringBuffer类(缓冲字符串处理类)。 下面先简单的说一下两者的区别。 String类和StringBuffer类都提供了相应的方法实现字符串的操作,但二者略有不
本文向大家介绍Java中StringBuffer和StringBuilder区别,包括了Java中StringBuffer和StringBuilder区别的使用技巧和注意事项,需要的朋友参考一下 早先用Java的时候,知道有个类叫StringBuffer,用来拼接较长的字符串。转到C#之后,也有一个似类功能的类叫作StringBuilder,简写都是sb,非常好记。 再后来转移回Java的时候,发