当前位置:   article > 正文

String、StringBuffer、StringBuilder原理详解_stringbuffer与stringbuilder对字符串操作的原理

stringbuffer与stringbuilder对字符串操作的原理

目录

1.String

1.1为什么String是不可变的

1.2 用 == 比较String对象

1.3 字符串的拼接 

1.3.1用 + 拼接,底层调用的是StringBuilder的append方法

1.3.2 用concat拼接

1.4 字符串的创建

2. AbstractStringBuilder

这个类是StringBuilder和StringBuffer的父类

3. StringBuffer (线程安全)

StringBuffer类继承了AbstractStringBuilder类,通过synchronized实现线程安全

3.1 StringBuffer的append(String str)方法

3.2 StringBuffer的toString()方法

3.3.StringBuffer创建对象

空参构造:字符数组初始长度为16

带参构造:字符数组初始长度为:16+字符串长度

4.StringBuilder (线程不安全)

StringBuilder类继承了AbstractStringBuilder类,没有synchronized,线程不安全

4.1 StringBuilder的一系列appen方法和toString()方法

5.用代码总结

5.1 关于拼接中null的总结:

5.2 关于new的总结:


1.String

1.1为什么String是不可变的

1.2 用 == 比较String对象


 

1.3 字符串的拼接 

  1. public class String与StringBuffer {
  2. public static void main(String[] args) {
  3. /**
  4. * String的拼接
  5. */
  6. String ss = "abc";
  7. String s1 = ss.concat("de");
  8. System.out.println(s1);//abcde
  9. String s2 = ss + "ef";
  10. System.out.println(s2);//abcef
  11. // String s3 = ss.concat(null);NullPointerException
  12. String s4 = ss + null;
  13. System.out.println(s4);//abcnull,因为底层调用的是StringBuilder的append方法
  14. }
  15. }

1.3.1用 + 拼接,底层调用的是StringBuilder的append方法,可以拼null

编译后:

1.3.2 用concat拼接,不能拼null(NullPointerException)

1.拼接的字符串如果为空,直接返回当前字符

2.创建一个新的字符数组,长度为当前字符串加上拼接的字符串,并把当前字符串拷贝进去

3.把拼接的字符串加到字符数组的后面,getChars -> arraycopy -> native方法

4.用字符数组创建新的字符串对象并返回

 

 

1.4 字符串的创建

  1. public class String与StringBuffer {
  2. public static void main(String[] args) {
  3. String str = new String();
  4. System.out.println("!"+str+"!");//!!
  5. }
  6. }

2. AbstractStringBuilder

这个类是StringBuilder和StringBuffer的父类

  1. abstract class AbstractStringBuilder implements Appendable, CharSequence {
  2. char[] value;
  3. int count;
  4. AbstractStringBuilder() {
  5. }
  6. AbstractStringBuilder(int capacity) {
  7. value = new char[capacity];
  8. }
  9. @Override
  10. public int length() {
  11. return count;
  12. }
  13. public int capacity() {
  14. return value.length;
  15. }
  16. private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
  17. public AbstractStringBuilder append(String str) {
  18. if (str == null)
  19. return appendNull();
  20. int len = str.length();
  21. ensureCapacityInternal(count + len);
  22. str.getChars(0, len, value, count);
  23. count += len;
  24. return this;
  25. }
  26. public AbstractStringBuilder append(StringBuffer sb) {
  27. if (sb == null)
  28. return appendNull();
  29. int len = sb.length();
  30. ensureCapacityInternal(count + len);
  31. sb.getChars(0, len, value, count);
  32. count += len;
  33. return this;
  34. }
  35. private AbstractStringBuilder appendNull() {
  36. int c = count;
  37. ensureCapacityInternal(c + 4);
  38. final char[] value = this.value;
  39. value[c++] = 'n';
  40. value[c++] = 'u';
  41. value[c++] = 'l';
  42. value[c++] = 'l';
  43. count = c;
  44. return this;
  45. }
  46. }

3. StringBuffer (线程安全)

StringBuffer类继承了AbstractStringBuilder类,通过synchronized实现线程安全

  1. public final class StringBuffer
  2. extends AbstractStringBuilder
  3. implements java.io.Serializable, CharSequence
  4. {
  5. private transient char[] toStringCache;
  6. //构造方法
  7. public StringBuffer() {
  8. super(16);//无参构造,字符数组初始容量为16
  9. }
  10. public StringBuffer(String str) {
  11. super(str.length() + 16);//参数是字符串的构造
  12. append(str);
  13. }
  14. @Override
  15. //参数可以是:Object obj,String str,StringBuffer sb,AbstractStringBuilder asb,
  16. //char[] str,boolean b,char c,int i,long lng,float f,double d
  17. public synchronized StringBuffer append(String str) {
  18. toStringCache = null;
  19. super.append(str);
  20. return this;
  21. }
  22. @Override
  23. public synchronized String toString() {
  24. if (toStringCache == null) {
  25. toStringCache = Arrays.copyOfRange(value, 0, count);
  26. }
  27. return new String(toStringCache, true);
  28. }
  29. }

3.1 StringBuffer的append(String str)方法,可以拼null

1.调用父类AbstractStringBuilder的append(String str)的方法

2.拼接字符串是不是null,如果是null,走appedNull()方法

3.字符数组扩容,大小为count + len,再把原有的字符数组复制到里面去

4.把拼接的字符串加到字符数组的后面,getChars -> arraycopy -> native方法

跟String的concat不同的地方:这里直接操作的是value这个成员变量,并把这个字符数组返回,因此SringBuffer是可变的。而String是创建了一个新的String对象并返回。

  1. public class String与StringBuffer {
  2. public static void main(String[] args) {
  3. /**
  4. * StringBuffer 线程安全的,用synchronized修饰了
  5. */
  6. //StringBuffer的append()方法
  7. StringBuffer sb4 = new StringBuffer();
  8. boolean b = false;
  9. sb4.append(b);
  10. System.out.println(sb4.toString());//false
  11. String sss = null;
  12. sb4.append(sss);
  13. System.out.println(sb4.toString());//falsenull
  14. }
  15. }

3.2 StringBuffer的toString()方法


被transient修饰,不参与序列化和反序列化

3.3.StringBuffer创建对象

空参构造:字符数组初始长度为16

 带参构造:字符数组初始长度为:16+字符串长度

  1. public class String {
  2. public static void main(String[] args) {
  3. StringBuffer sb3 = new StringBuffer();
  4. String s5 = sb3.toString();
  5. System.out.println("!" + s5 + "!");//!!
  6. }
  7. }

4.StringBuilder (线程不安全)

StringBuilder类继承了AbstractStringBuilder类,没有synchronized,线程不安全

4.1 StringBuilder的一系列appen方法和toString()方法

一系列的append方法,调用的是父类AbstractStringBuilder 的方法

  1. public final class StringBuilder
  2. extends AbstractStringBuilder
  3. implements java.io.Serializable, CharSequence{
  4. @Override
  5. public StringBuilder append(Object obj) {
  6. return append(String.valueOf(obj));
  7. }
  8. @Override
  9. public StringBuilder append(String str) {
  10. super.append(str);
  11. return this;
  12. }
  13. public StringBuilder append(StringBuffer sb) {
  14. super.append(sb);
  15. return this;
  16. }
  17. @Override
  18. public StringBuilder append(CharSequence s) {
  19. super.append(s);
  20. return this;
  21. }
  22. @Override
  23. public StringBuilder append(CharSequence s, int start, int end) {
  24. super.append(s, start, end);
  25. return this;
  26. }
  27. @Override
  28. public StringBuilder append(char[] str) {
  29. super.append(str);
  30. return this;
  31. }
  32. @Override
  33. public StringBuilder append(char[] str, int offset, int len) {
  34. super.append(str, offset, len);
  35. return this;
  36. }
  37. @Override
  38. public StringBuilder append(boolean b) {
  39. super.append(b);
  40. return this;
  41. }
  42. @Override
  43. public StringBuilder append(char c) {
  44. super.append(c);
  45. return this;
  46. }
  47. @Override
  48. public StringBuilder append(int i) {
  49. super.append(i);
  50. return this;
  51. }
  52. @Override
  53. public StringBuilder append(long lng) {
  54. super.append(lng);
  55. return this;
  56. }
  57. @Override
  58. public StringBuilder append(float f) {
  59. super.append(f);
  60. return this;
  61. }
  62. @Override
  63. public StringBuilder append(double d) {
  64. super.append(d);
  65. return this;
  66. }
  67. @Override
  68. public String toString() {
  69. // Create a copy, don't share the array
  70. return new String(value, 0, count);
  71. }
  72. }
 

5.代码总结

5.1 关于拼接中null的总结:

StringBuffer、StringBuilder可以append一个null

String不能concat一个null,会报空指针

String可以+null(底层调用的是StringBuilder的append方法)

5.2 关于new的总结:

如果是空参构造创建了一个String对象,初始化为""

如果是空参构造创建了StringBuffer或StringBuilder对象,初始化一个字符数组,长度是16

打印出来都是""

  1. public class String与StringBuffer {
  2. public static void main(String[] args) {
  3. /**
  4. * String的拼接方法
  5. */
  6. String ss = "abc";
  7. String s1 = ss.concat("de");
  8. System.out.println(s1);//abcde
  9. String s2 = ss + "ef";
  10. System.out.println(s2);//abcef
  11. // String s3 = ss.concat(null);NullPointerException
  12. String s4 = ss + null;
  13. System.out.println(s4);//abcnull,因为底层调用的是StringBuilder的append方法
  14. String str = new String();
  15. System.out.println("!"+str+"!");//!!
  16. /**
  17. * String => StringBuffer
  18. */
  19. String s = "hello";
  20. //方式1:通过构造方法
  21. StringBuffer sb1 = new StringBuffer(s);
  22. System.out.println(sb1);//hello
  23. //方法2:通过append方法
  24. StringBuffer sb2 = new StringBuffer();
  25. sb2.append(s);
  26. System.out.println(sb2.toString());//hello
  27. /**
  28. * StringBuffer => String
  29. */
  30. StringBuffer buffer = new StringBuffer("world");
  31. //方法1:通过构造方法
  32. String str1 = new String(buffer);
  33. System.out.println(str1);//world
  34. //方法2:通过toString方法
  35. //任何引用类型调用toString方法都可以转成字符串
  36. String str2 = buffer.toString();
  37. System.out.println(str2);//world
  38. /**
  39. * StringBuffer 线程安全的,用synchronized修饰了
  40. */
  41. //StringBuffer的toString()方法
  42. StringBuffer sb3 = new StringBuffer();
  43. String s5 = sb3.toString();
  44. System.out.println("!" + s5 + "!");//!!
  45. //StringBuffer的append()方法
  46. StringBuffer sb4 = new StringBuffer();
  47. boolean b = false;
  48. sb4.append(b);
  49. System.out.println(sb4.toString());//false
  50. String sss = null;
  51. sb4.append(sss);
  52. System.out.println(sb4.toString());//falsenull
  53. /**
  54. * StringBuilder 线程不安全
  55. */
  56. StringBuilder sb5 = new StringBuilder();
  57. sb5.append(false);
  58. System.out.println(sb5.toString());//false
  59. String s6 = null;
  60. sb5.append(s6);
  61. System.out.println(sb5.toString());//falsenull
  62. }
  63. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/657450
推荐阅读
相关标签
  

闽ICP备14008679号