在自己以往的学习及工作经验中,形成的概念:
String对象具有不变性,一旦String对象生成,就不可能在被改变;
StringBuffer 线程安全;
StringBuilder 线程不安全;
现针对以上三种Object,在自己机器上手写代码做测试,以验证三者的效率差异:
三种Object同时在3种不同的字符串拼接中,循环5w次,耗时对比:
Source Code: Test.java
public class Test { static int len = 50000; public static void main(String[] args) { System.out.println("---testOne()---"); testOne(); System.out.println("---testTwo()---"); testTwo(); System.out.println("---testThree()---"); testThree(); } static void testOne() { Long t1 = System.currentTimeMillis(); for (int i = 0; i < len; i++) { String result1 = "String" + "and" + "String" + "append"; } Long t2 = System.currentTimeMillis(); for (int i = 0; i < len; i++) { StringBuffer sb = new StringBuffer(); sb.append("String"); sb.append("and"); sb.append("String"); sb.append("append"); } Long t3 = System.currentTimeMillis(); for (int i = 0; i < len; i++) { StringBuilder sb = new StringBuilder(); sb.append("String"); sb.append("and"); sb.append("String"); sb.append("append"); } Long t4 = System.currentTimeMillis(); System.out.println("String:" + (t2 - t1)+"ms"); System.out.println("StringBuffer:" + (t3 - t2)+"ms"); System.out.println("StringBuilder:" + (t4 - t3)+"ms"); } static void testTwo() { String temp = "abcd"; String temp2 = "abcd"; String temp3 = "abcd"; Long t1 = System.currentTimeMillis(); for (int i = 0; i < len; i++) { String result1 = temp + temp2 + temp3; } Long t2 = System.currentTimeMillis(); for (int i = 0; i < len; i++) { StringBuffer sb = new StringBuffer(); sb.append(temp); sb.append(temp2); sb.append(temp3); } Long t3 = System.currentTimeMillis(); for (int i = 0; i < len; i++) { StringBuilder sb = new StringBuilder(); sb.append(temp); sb.append(temp2); sb.append(temp3); } Long t4 = System.currentTimeMillis(); System.out.println("String:" + (t2 - t1)+"ms"); System.out.println("StringBuffer:" + (t3 - t2)+"ms"); System.out.println("StringBuilder:" + (t4 - t3)+"ms"); } static void testThree() { String temp = "abcd"; String temp2 = "abcd"; String temp3 = "abcd"; Long t1 = System.currentTimeMillis(); for (int i = 0; i < len; i++) { String result1 = "String" + "and" + "String" + "append" + temp + temp2 + temp3; } Long t2 = System.currentTimeMillis(); for (int i = 0; i < len; i++) { StringBuffer sb = new StringBuffer(); sb.append("String"); sb.append("and"); sb.append("String"); sb.append("append"); sb.append(temp); sb.append(temp2); sb.append(temp3); } Long t3 = System.currentTimeMillis(); for (int i = 0; i < len; i++) { StringBuilder sb = new StringBuilder(); sb.append("String"); sb.append("and"); sb.append("String"); sb.append("append"); sb.append(temp); sb.append(temp2); sb.append(temp3); } Long t4 = System.currentTimeMillis(); System.out.println("String:" + (t2 - t1)+"ms"); System.out.println("StringBuffer:" + (t3 - t2)+"ms"); System.out.println("StringBuilder:" + (t4 - t3)+"ms"); } }
反编译Test.class
import java.io.PrintStream; public class Test { static int len = 50000; public static void main(String[] args) { System.out.println("---testOne()---"); testOne(); System.out.println("---testTwo()---"); testTwo(); System.out.println("---testThree()---"); testThree(); } static void testOne() { Long t1 = Long.valueOf(System.currentTimeMillis()); for (int i = 0; i < len; i++) { String str = "StringandStringappend"; } Long t2 = Long.valueOf(System.currentTimeMillis()); for (int i = 0; i < len; i++) { StringBuffer sb = new StringBuffer(); sb.append("String"); sb.append("and"); sb.append("String"); sb.append("append"); } Long t3 = Long.valueOf(System.currentTimeMillis()); for (int i = 0; i < len; i++) { StringBuilder sb = new StringBuilder(); sb.append("String"); sb.append("and"); sb.append("String"); sb.append("append"); } Long t4 = Long.valueOf(System.currentTimeMillis()); System.out.println("String:" + (t2.longValue() - t1.longValue()) + "ms"); System.out.println("StringBuffer:" + (t3.longValue() - t2.longValue()) + "ms"); System.out.println("StringBuilder:" + (t4.longValue() - t3.longValue()) + "ms"); } static void testTwo() { String temp = "abcd"; String temp2 = "abcd"; String temp3 = "abcd"; Long t1 = Long.valueOf(System.currentTimeMillis()); for (int i = 0; i < len; i++) { String str1 = temp + temp2 + temp3; } Long t2 = Long.valueOf(System.currentTimeMillis()); for (int i = 0; i < len; i++) { StringBuffer sb = new StringBuffer(); sb.append(temp); sb.append(temp2); sb.append(temp3); } Long t3 = Long.valueOf(System.currentTimeMillis()); for (int i = 0; i < len; i++) { StringBuilder sb = new StringBuilder(); sb.append(temp); sb.append(temp2); sb.append(temp3); } Long t4 = Long.valueOf(System.currentTimeMillis()); System.out.println("String:" + (t2.longValue() - t1.longValue()) + "ms"); System.out.println("StringBuffer:" + (t3.longValue() - t2.longValue()) + "ms"); System.out.println("StringBuilder:" + (t4.longValue() - t3.longValue()) + "ms"); } static void testThree() { String temp = "abcd"; String temp2 = "abcd"; String temp3 = "abcd"; Long t1 = Long.valueOf(System.currentTimeMillis()); for (int i = 0; i < len; i++) { String str1 = "StringandStringappend" + temp + temp2 + temp3; } Long t2 = Long.valueOf(System.currentTimeMillis()); for (int i = 0; i < len; i++) { StringBuffer sb = new StringBuffer(); sb.append("String"); sb.append("and"); sb.append("String"); sb.append("append"); sb.append(temp); sb.append(temp2); sb.append(temp3); } Long t3 = Long.valueOf(System.currentTimeMillis()); for (int i = 0; i < len; i++) { StringBuilder sb = new StringBuilder(); sb.append("String"); sb.append("and"); sb.append("String"); sb.append("append"); sb.append(temp); sb.append(temp2); sb.append(temp3); } Long t4 = Long.valueOf(System.currentTimeMillis()); System.out.println("String:" + (t2.longValue() - t1.longValue()) + "ms"); System.out.println("StringBuffer:" + (t3.longValue() - t2.longValue()) + "ms"); System.out.println("StringBuilder:" + (t4.longValue() - t3.longValue()) + "ms"); } }
测试运行结果:
将len设为50w,运行结果差异会更大;
总结:
对一个注重执行效率的系统,应该根据实际当中不同的业务需求,按需选用String, StringBuffer 或 StringBuilder。
----------------
相关推荐
javase部分String的相关基础知识,String的构造方法总结比较以及各自的应用场景(代码举例),常用的容器类StringBuilder和StringBuffer的关系比较(图示)以及两者的区别联系和具体哪中场景下用哪个类。
利用 `StringBuilder` 或 `StringBuffer` 修改字符串: ```java String s = "abc"; StringBuilder sb = new StringBuilder(s); sb.setCharAt(0, 'd'); s = sb.toString(); ``` 这段代码首先使用 `StringBuilder` ...
8. String、StringBuilder和StringBuffer之间的区别? String是不可变的。每次对String做修改时,都会生成新的String对象。而StringBuilder和StringBuffer都是可变的字符串,意味着它们的内容可以被改变。...
2. 使用 StringBuffer 而不是 StringBuilder:StringBuffer 是线程安全的,但它的性能较差,而 StringBuilder 是非线程安全的,但它的性能较好。修改建议:使用 StringBuilder 替代 StringBuffer。 代码举例: ```...
9、 String、StringBuffer、StringBuilder 的区别 10、 同步和异步有何异同,在什么情况下分别使用他们?举例说明。 .............................................. ...............................................
3. **String与StringBuilder/StringBuffer的区别**: - **String**:不可变对象,每次修改都会创建新对象,不适合大量修改操作。 - **StringBuilder/StringBuffer**:可变对象,允许在原对象基础上修改,...
因此,当我们进行文本操作时,通常会使用`String`的内置方法或`StringBuilder`、`StringBuffer`类。 1. **查找指定字符串**:在Java中,我们可以使用`indexOf()`方法来查找指定字符串。例如,如果我们要找到一段...
因为每次使用String连接都会创建新的String对象,而StringBuilder和StringBuffer在内部是以数组的方式存储字符串,仅在必要时才进行数组扩容操作,从而减少垃圾回收的次数。 3. 局部变量的使用 尽可能地使用局部...
- 在多线程环境中,StringBuffer是线程安全的,而StringBuilder不是,但在单线程环境下StringBuilder效率更高。 5. **运行时异常与一般异常有何异同?** - 运行时异常是程序设计或逻辑错误,如空指针异常、数组...
- 在循环中使用“+”连接字符串通常比使用StringBuilder或StringBuffer性能更差,因为会生成很多临时的String对象。 ### 第六章 Java的数据类型 1. **基本数据类型** - Java的基本数据类型包括byte、short、int...
3. **性能**:在单线程环境中,频繁修改字符串时,`StringBuilder`(`StringBuffer`的非线程安全版本)相比`StringBuffer`更高效,因为后者每次调用方法都要进行加锁和解锁。 #### 五、运行时异常与一般异常的异同 ...
5. **颠倒字符串**:可以使用StringBuilder或StringBuffer的reverse()方法来高效地颠倒字符串。 6. **int 和 Integer 的区别**:int 是基本数据类型,直接存储值,而 Integer 是其包装类,是对象,可以进行null值...
- `StringBuffer`在多线程环境中是同步的,因此比`StringBuilder`更安全但效率较低。 5. **运行时异常与一般异常的异同:** - **相同点**:异常都是程序执行过程中可能发生的错误情况。 - **不同点**: - 运行...
- **StringBuffer** 和 **StringBuilder**:可变,适合大量修改操作。 - **StringBuffer**:线程安全。 - **StringBuilder**:非线程安全,性能更高。 **35. 如何把一段逗号分割的字符串转换成一个数组?** 可以...
这条语句创建了 3 个 `String` 对象和 1 个 `StringBuilder` 或 `StringBuffer` 对象(取决于编译器优化)。 **38. try{} 里有一个 return 语句,那么紧跟在这个 try 后的 finally{} 里的 code 会不会被执行,什么...