深入java字符串原理及其效率分析

  • java字符串类基本特点
  1. String类是final的,不可继承
  2. String类源码实现通过字符数组实现,长度不可改变
  3. 可以通过String str = "123"来创建一个String对象
  4. 通过+可以将两个String对象串联,生成新的字符串
  5. java运行时会维护一个字符串池,String池会保存程序运行中产生的各种字符串,这些字符串内容不能相同

  • 字符串创建的几种方式
  1. 使用new关键字创建  String str = new String("str");
  2. String str  = "a";
  3. String str = "a",String str2 = str + "bb";

  • 字符串创建的关键原理
  1. 通过任何方式创建的字符串都会在字符串池中查找该字符串是否存在,如果不存在则向字符串池中添加该字符串
  2. 通过new关键字创建的字符串,会在堆栈中创建一个新的对象
  3. 通过String str  = "aa"+"bb"; 方式创建创建字符串,java只会维护其在字符串池中是否存在
  4. 如果通过字符串拼接所创建的字符串中存在变量,那么java会在堆栈区中创建一个对象

      字符串的不同创建位置比较

  1. /**
  2. *
  3. * 几种字符串创建方式的比较
  4. *
  5. */
  6. public static void compare()
  7. {
  8. //指向对象池中的"abc",不在堆栈中创建对象
  9. String str1 = "abc";
  10. //指向对象池中的"abc",不在堆栈中创建对象
  11. String str2 = str1;
  12. //在堆栈中创建,指向对象
  13. String str3 = new String("abc");
  14. //指向对象池中的"abc",不在堆栈中创建对象
  15. String str4 = "a"+"bc";
  16. String a = "c";
  17. //在堆栈中创建对象,并指向该对象
  18. String str5 = "ab" + a;
  19. //在堆栈中创建对象,并指向该对象
  20. String str6 = "ab".concat(a);
  21. //在堆栈中创建对象,并指向该对象
  22. String str7 = "ab".concat("c");
  23.  
  24. System.out.println(str1==str2);//true
  25. System.out.println(str1==str3);//false
  26. System.out.println(str1==str4);//true
  27. System.out.println(str1==str5);//false
  28. System.out.println(str1==str6);//false
  29. System.out.println(str1==str7);//false
  30. System.out.println(str3==str4);//false
  31. System.out.println(str3==str5);//false
  32. System.out.println(str3==str6);//false
  33. System.out.println(str3==str7);//false
  34. }
  35.  
  36. /**
  37. * 采用不同的方式创建空字符串
  38. */
  39. public static void compareEmpty()
  40. {
  41. String str1 = new String("");
  42. String str2 = "";
  43. String str3 = new String("");
  44. //intern()方法会判断字符串是否在字符串池中,如果存在直接返回引用即可
  45. String str4 = "".intern();
  46. String str5 = ""+"";
  47. //trim()方法会在堆栈中创建一个对象
  48. String str6 = " ".trim();
  49. String str7 = " ";
  50. String str8 = " ".trim();
  51. String str9 = "".concat("");
  52.  
  53. System.out.println(str1==str2);//false
  54. System.out.println(str1==str3);//false
  55. System.out.println(str1==str4);//false
  56. System.out.println(str1==str5);//false
  57. System.out.println(str1==str6);//false
  58. System.out.println(str1==str7);//false
  59. System.out.println(str1==str8);//false
  60. System.out.println(str1==str9);//false
  61. System.out.println(str2==str3);//false
  62. System.out.println(str2==str6);//false
  63. System.out.println(str2==str8);//true
  64. System.out.println(str2==str9);//false
  65. System.out.println(str6==str8);//false**
  66.  
  67. }

字符串操作中的效率问题

字符串的切分算法采用StringTokenizer的效率优于String的Split方法,字符串切分中StringToken的效率优于split方法
字符串的拼接中采用StringBuilder的效率高于字符串相加或者new String().concat()方法,因为字符串相加或者拼接的方式都会在对象池中查找字符串是否存在,如果不存在则创建,这样在拼接的过程中会产生大量中间过程的字符串,占用内存资源,StringBuilder效率优于StringBuffer,但是StringBuffer线程安全


原文地址:https://www.cnblogs.com/zhuyeshen/p/12103481.html