0%

Java 常用基础类(三):剖析 StringBuilder

1. 怎么理解 StringBuilderStringBuffer

  • 如果字符串修改操作比较频繁,应该采用 StringBuilderStringBuffer
  • 这两个类的方法基本是完全一样的,它们的实现代码也几乎一样。唯一的不同就在于 StringBuffer 类是线程安全的,而 StringBuilder 类不是
  • 线程安全是有成本的,影响性能,而字符串对象及操作大部分情况下不存在线程安全问题

2. StringBuilder 的基本用法

  1. 通过 new 新建 StringBuilder 对象
  2. 通过 append() 方法添加字符串
  3. 通过 toString() 方法获取构建完成的字符串

3. StringBuilder 的实现原理

  • 源码基于 Java 7
    • String 类似,StringBuilder 类内部也封装了一个字符数组 char[] value,与 String 不同的是,它不是 final,可以修改
    • 另外,与 String 不同,字符数组中不一定所有位置都已经被使用,它有一个实例变量 int count 表示数组中已经使用的字符个数
    • StringBuilder 继承自 AbstractStringBuilder,它的默认构造方法是:public StringBuilder() { super(16); }

4. StringBuilder 类的 append() 方法的实现原理

  • 如果字符数组的长度小于需要的长度,则调用 void expandCapacity(int minimumCapacity) 方法进行容量扩展
  • 扩容的逻辑是:分配一个足够长度的新数组,然后将原内容复制到这个新数组中,最后让内部的字符数组指向这个新数组。其中,newCapacity 的计算方法是:int newCapacity = value.length * 2 + 2;

5. 为什么不能需要多少就分配多少

  • 不能
  • 因为那就跟 String 一样了,每 append 一次,都会进行一次内存分配,效率低下

6. 这种扩展策略最后为什么要加 2

  • 这是一种指数扩展策略
  • 加 2 的原因是在原长度为 0 时也可以一样工作

7. 为什么要这样扩展

  • 这是一种折中策略,一方面要减少内存分配的次数,另一方面要避免空间浪费
  • 在不知道最终需要多长的情况下,指数扩展是一种常见的策略,广泛应用于各种内存分配相关的计算机程序中

8. 怎样理解 native 关键字

  • native 关键字是一个修饰符,表示它修饰的方法的实现是通过 Java 本地接口实现的
  • Java 本地接口(JNI)是 Java 提供的一种技术,用于在 Java 中调用非 Java 实现的代码
  • 实际上,insert() 方法中的用 native 修饰的 System.arraycopy() 方法使用 C++ 语言实现的。之所以用 C++ 语言实现是因为这个功能非常常用,而 C++ 的实现效率要远高于 Java

9. String 可以直接使用 +/+= 运算符的背后原理是什么

  • 这是 Java 编译器提供的支持
  • 背后,Java 编译器一般会生成 StringBuilder++= 操作会转换为调用 append() 方法

10. 既然直接使用 ++= 就相当于使用 StringBuilderappend(),那还有什么必要直接使用 StringBuilder

  • 在简单的情况下,确定没必要
  • 在稍微复杂的情况下,Java 编译器可能没有那么智能,它可能会生成过多的 StringBuilder,尤其是在有循环的情况下
  • 所以,对于简单的情况,可以直接使用 String++=;对于复杂的情况,尤其是有循环的时候,应该直接使用 StringBuilder
-------------------- 本文结束感谢您的阅读 --------------------