当前位置:  首页>> 技术小册>> Java语言基础9-常用API和常见算法

1.6.1 拼接结果的存储和比较问题

  • 原则:

    • 常量+常量:结果是常量池。
    • 常量和变量 或 变量和变量:结果是堆。
    • 拼接后调用 intern 方法:结果在常量池。
  • 示例:

  1. package com.github.string.demo7;
  2. /**
  3. * @author maxiaoke.com
  4. * @version 1.0
  5. *
  6. */
  7. public class Test {
  8. public static void main(String[] args) {
  9. String s1 = "hello";
  10. String s2 = "world";
  11. String s3 = "helloworld";
  12. String s4 = (s1 + "world").intern(); // 将拼接的结果放在常量池中
  13. String s5 = (s1 + s2).intern();
  14. System.out.println(s3 == s4); // true
  15. System.out.println(s3 == s5); // true
  16. }
  17. }
  • 示例:
  1. package com.github.string.demo8;
  2. /**
  3. * @author maxiaoke.com
  4. * @version 1.0
  5. *
  6. */
  7. public class Test {
  8. public static void main(String[] args) {
  9. final String s1 = "hello";
  10. final String s2 = "world";
  11. String s3 = "helloworld";
  12. String s4 = s1 + "world"; // s1是常量,"world"也是常量,所以s4是常量
  13. String s5 = s1 + s2; // s1是常量,s2是常量,所以s5是常量
  14. String s6 = "hello" + "world"; // "hello"是常量,"world"是常量,所以s6是常量
  15. System.out.println(s3 == s4); // true
  16. System.out.println(s3 == s5); // true
  17. System.out.println(s3 == s6); // true
  18. }
  19. }
  • 示例:
  1. package com.github.string.demo9;
  2. /**
  3. * @author maxiaoke.com
  4. * @version 1.0
  5. *
  6. */
  7. public class Test {
  8. public static void main(String[] args) {
  9. String s1 = "hello";
  10. String s2 = "world";
  11. String s3 = "helloworld";
  12. String s4 = s1 + "world"; // s1是变量,"world"是常量,所以s4是变量
  13. String s5 = s1 + s2; // s1是变量,s2是变量,所以s5是变量
  14. String s6 = "hello" + "world"; // "hello"是常量,"world"是常量,所以s6是常量
  15. System.out.println(s3 == s4); // false
  16. System.out.println(s3 == s5); // false
  17. System.out.println(s3 == s6); // true
  18. }
  19. }

1.6.2 拼接效率问题

  • 示例:
  1. package com.github.string.demo10;
  2. /**
  3. * @author maxiaoke.com
  4. * @version 1.0
  5. *
  6. */
  7. public class Test {
  8. public static void main(String[] args) {
  9. String str = "0";
  10. for (int i = 0; i < 5; i++) {
  11. str += i;
  12. }
  13. System.out.println("str = " + str);
  14. }
  15. }

不过,现在的 JDK 版本,都会使用可变字符序列对如上的代码优化,不信,反编译查看字节码:

  1. javap -c Test.class
  1. Compiled from "Test.java"
  2. public class com.github.string.demo10.Test {
  3. public com.github.string.demo10.Test();
  4. Code:
  5. 0: aload_0
  6. 1: invokespecial #1 // Method java/lang/Object."<init>":()V
  7. 4: return
  8. public static void main(java.lang.String[]);
  9. Code:
  10. 0: ldc #2 // String 0
  11. 2: astore_1
  12. 3: iconst_0
  13. 4: istore_2
  14. 5: iload_2
  15. 6: iconst_5
  16. 7: if_icmpge 35
  17. 10: new #3 // class java/lang/StringBuilder
  18. 13: dup
  19. 14: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
  20. 17: aload_1
  21. 18: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  22. 21: iload_2
  23. 22: invokevirtual #6 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
  24. 25: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
  25. 28: astore_1
  26. 29: iinc 2, 1
  27. 32: goto 5
  28. 35: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream;
  29. 38: new #3 // class java/lang/StringBuilder
  30. 41: dup
  31. 42: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
  32. 45: ldc #9 // String str =
  33. 47: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  34. 50: aload_1
  35. 51: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  36. 54: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
  37. 57: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
  38. 60: return
  39. }

1.6.3 concat 方法拼接

  • concat() 方法拼接,哪怕是两个常量对象拼接,结果也是在堆中。

  • 示例:

  1. package com.github.string.demo19;
  2. /**
  3. * @author maxiaoke.com
  4. * @version 1.0
  5. *
  6. */
  7. public class Test {
  8. public static void main(String[] args) {
  9. String s1 = "hello";
  10. String s2 = "world";
  11. String s3 = "helloworld";
  12. String s4 = "hello".concat("world");
  13. String s5 = "hello" + "world";
  14. System.out.println(s3 == s4); // false
  15. System.out.println(s3 == s5); // true
  16. System.out.println(s1 + s2 == s5); // false
  17. }
  18. }