JDK1.7源码笔记之StringBuilder和StringBuffer类
来源:互联网 发布:origin8怎么数据拟合 编辑:程序博客网 时间:2024/05/18 05:18
1. class 简介
StringBuilder类和StringBuffer类的功能几乎一模一样,除了后者是多线程安全的,而前者主要用于单线程环境,是从性能考虑上对StringBuffer的替代。它们最主要的操作是拼接和插入,还附带转置和删除字符串的操作,String类的一些方法StringBuilder和StringBuffer多少也有一些,但是这两个类的任何操作都是在原字符串上进行的。它们都从AbstractStringBuilder类继承而来,大部分的操作都发生在父类。
2. class内部原理及特点
- 在其父类AbstractStringBuilder中维护了一个字符数组,和String不同的是,没有final修饰,所以是可变的,默认容量为16,传入字符串进行初始化时容量为其长度增加16。
- 扩容时总容量*2+2,如果容量仍然不够用,则直接扩充为要求长度。
- 拼接和插入时都使用System.arraycopy,除非扩容时可能产生新的字符数组,一般情况不会出现中间对象,所以效率比String类要高。
3. class源码细节分析
StringBuilder和StringBuffer类的核心都在其父类AbstractStringBuilder类中,所以只需要看AbstractStringBuilder类中的一些具有代表性的方法。
expandCapacity
void expandCapacity(int minimumCapacity) { int newCapacity = value.length * 2 + 2;//容量*2+2 if (newCapacity - minimumCapacity < 0)//不够就直接为所需长度 newCapacity = minimumCapacity; if (newCapacity < 0) { if (minimumCapacity < 0) // overflow throw new OutOfMemoryError(); newCapacity = Integer.MAX_VALUE; } //产生了新的字符数组,改变了原来的字符串 value = Arrays.copyOf(value, newCapacity);}
append
public AbstractStringBuilder append(String str) { if (str == null) str = "null"; int len = str.length(); ensureCapacityInternal(count + len);//看下要不要扩容 str.getChars(0, len, value, count);//把参数str复制到value字符数组中,整个拼接过程可能不会产生新对象 count += len; //性能必然比String的+和concat要好 return this;}
其它类型的拼接都差不多,不是字符类型的先转换成字符,再复制到value中。
insert
public AbstractStringBuilder insert(int offset, String str) { if ((offset < 0) || (offset > length())) throw new StringIndexOutOfBoundsException(offset); if (str == null) str = "null"; int len = str.length(); ensureCapacityInternal(count + len);//是否需要扩容 System.arraycopy(value, offset, value, offset + len, count - offset);//插入点后的字符往后挪,腾出空间来 str.getChars(value, offset); //把待插入字符串复制到offset插入点 count += len; return this;}
其它类型数据的插入都是大同小异,没有特别的地方。
delete
public AbstractStringBuilder delete(int start, int end) { if (start < 0) throw new StringIndexOutOfBoundsException(start); if (end > count) end = count; if (start > end) throw new StringIndexOutOfBoundsException(); int len = end - start; if (len > 0) { System.arraycopy(value, start+len, value, start, count-end);//把后面的往前面覆盖 count -= len; } return this;}
reverse
public AbstractStringBuilder reverse() { boolean hasSurrogate = false; int n = count - 1; for (int j = (n-1) >> 1; j >= 0; --j) {//从中间位置开始 char temp = value[j]; char temp2 = value[n - j]; if (!hasSurrogate) { hasSurrogate = (temp >= Character.MIN_SURROGATE && temp <= Character.MAX_SURROGATE) || (temp2 >= Character.MIN_SURROGATE && temp2 <= Character.MAX_SURROGATE); } value[j] = temp2;//左半边和右半边交换位置 value[n - j] = temp; } if (hasSurrogate) {//代理对的问题跳过 // Reverse back all valid surrogate pairs for (int i = 0; i < count - 1; i++) { char c2 = value[i]; if (Character.isLowSurrogate(c2)) { char c1 = value[i + 1]; if (Character.isHighSurrogate(c1)) { value[i++] = c1; value[i] = c2; } } } } return this;}
4. 总结
如果要对字符串进行频繁的操作,StringBuilder和StringBuffer的性能肯定要更好,或许在转换成StringBuilder或StringBuffer对象时会多一些开销,但是和频繁操作中带来的优势相比,这点就不足为虑了;StringBuilder比StringBuffer使用的更加广泛,毕竟多线程操作同一个字符串的情况实在少见。
1 0
- JDK1.7源码笔记之StringBuilder和StringBuffer类
- JDK源码解析之StringBuilder和StringBuffer
- JAVA基础笔记之StringBuilder和StringBuffer
- String类和StringBuffer,StringBuilder笔记
- StringBuilder和StringBuffer源码浅析
- StringBuilder和StringBuffer源码分析
- JDK1.8源码阅读之——String,StringBuffer, StringBuilder
- Java学习之StringBuffer 和 StringBuilder 类
- JDK1.7源码笔记之Arrays类
- JDK1.7源码笔记之String类
- JDK1.7源码笔记之ArrayList类
- JDK1.7源码笔记之LinkedList类
- JDK1.7源码笔记之ArrayDeque类
- JDK1.7-StringBuilder源码详解
- StringBuilder和StringBuffer类
- StringBuffer 和 StringBuilder 类
- StringBuffer和StringBuilder类
- 【源码】StringBuilder和StringBuffer源码深度剖析
- js模版方法模式
- Java开发必备技术Junit测试技术学习---源代码演示Junit
- linux学习初体验
- 螺旋方阵
- 单链表
- JDK1.7源码笔记之StringBuilder和StringBuffer类
- websphere控制台无法登入
- 登录界面的设计
- 12.table
- 在JavaScript12项有用的技术
- 性能测试的概念及其分类
- 第X大的数
- min栈实现
- 微服务指南走北(四):你不愿意做微服务架构的十个理由