Java源码阅读之StringBuffer
2016-03-07 18:52
453 查看
Summary:
只是导入了import java.util.Arrays;public final class StringBuffer extends AbstractStringBuilder;父类是一个StringBuidler的抽象类
String Buffer中的很多方法使用了关键字Synchronized,所以是线程安全的
与String的区别就是字符数组不是声明为final;中间的对于字符的修改除了setCharAt方法没有使用System.arraycopy方法外,其它方法都是调用了这个方法进行实现的;
可以通过trimToSize()方法进行减容,Capacity减到当前存有的数据大小
Fields:
private transient char[] toStringCache; <span style="font-family: 微软雅黑; font-size: 14px; line-height: 21px; widows: auto;">//toStringCache的作用是缓存上次返回String对应的char数组的引用,详参toString方法</span>
父类有两个域: char[] value; //数据的引用 int count; //记录当前存储的数据长度,小于等于value.length
Constructor:
//参考AbstractStringBuilder可以知道是创建一个长度为16的字符数组 public StringBuffer() { super(16); } //参考AbstractStringBuilder可以知道是创建一个长度为str.length()+16的字符数组 public StringBuffer(String str) { super(str.length() + 16); append(str); }
length():
//返回当前存储的字符数 @Override public synchronized int length() { return count; }
charAt():
//等同于数组的随机访问操作; @Override public synchronized char charAt(int index) { if ((index < 0) || (index >= count)) throw new StringIndexOutOfBoundsException(index); return value[index]; }
getChars():
//父类最终是调用System.arraycopy方法,从父类的value中取出目标中的字符存入到目标字符数组中 @Override public synchronized void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) { super.getChars(srcBegin, srcEnd, dst, dstBegin); }
capacity():
//返回能当前容器的容量大小; @Override public synchronized int capacity() { return value.length; }
append():
//调用父类中append方法; @Override public synchronized StringBuffer append(XX str) { toStringCache = null; super.append(str); return this; } //以下是父类AbstractStringBuilder的append方法 //将XX中的字符复制到value数组中,同时更新count值 public AbstractStringBuilder append(XX str) { if (str == null) return appendNull(); int len = str.length(); ensureCapacityInternal(count + len);//确保当前的value容量足够的大! str.getChars(0, len, value, count); //String的getChars方法 count += len; return this; } //以下是父类AbstractStringBuilder的ensureCapacityInternal方法 //如果当前容量小于需求容量则扩容 private void ensureCapacityInternal(int minimumCapacity) { // overflow-conscious code if (minimumCapacity - value.length > 0) expandCapacity(minimumCapacity); } //以下是父类AbstractStringBuilder的expandCapacity方法 //首先扩容两倍,如果扩容后还是小于当前要求最小容量则扩容容量到当前要求最小容量 //最后判断如果容量大于Integer.MAX_VALUE;则赋值Integer.MAX_VALUE //最后将当前的value值赋值到新的char数组中; void expandCapacity(int minimumCapacity) { int newCapacity = value.length * 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); }
减容
public void trimToSize() { if (count < value.length) { value = Arrays.copyOf(value, count); } }
insert();
//调用父类的insert方法 @Override public synchronized StringBuffer insert(int offset, String str) { toStringCache = null; super.insert(offset, str); return this; } //首先将offset到count的数据往后移动str.length()长度 //随后调用string的getChars方法将str中的数据存入value中 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); count += len; return this; }
setCharAt():
//修改父类中value域的值,String类中不能进行该操作!<span style="color:#ff6666;">注意此处没有使用synchronized</span> public void setCharAt(int index, char ch) { if ((index < 0) || (index >= count)) throw new StringIndexOutOfBoundsException(index); value[index] = ch; }
delete():
@Override public synchronized StringBuffer delete(int start, int end) { toStringCache = null; super.delete(start, end); return this; } //以下是父类AbstractStringBuilder的 delete方法 //将value在end后面的数据移动到start前面来 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; } //java.lang.System.arraycopy方法声明为public static native void arraycopy( Object src, int srcPos, Object dest, int destPos, int length);
deleteCharAt();
//其底层实现方式跟delete()方法一样都是调用System.arraycopy public AbstractStringBuilder deleteCharAt(int index) { if ((index < 0) || (index >= count)) throw new StringIndexOutOfBoundsException(index); System.arraycopy(value, index+1, value, index, count-index-1); count--; return this; }
toString();
@Override public synchronized String toString() { if (toStringCache == null) { toStringCache = Arrays.copyOfRange(value, 0, count); } return new String(toStringCache, true); }
相关文章推荐
- jQuery和js 获取父级元素、子级元素、兄弟元素方法
- css一些零零散散的问题
- JavaScript对象创建方法大全
- LeetCode : Remove Nth Node From End of List [java]
- extjs column列布局
- Java EE 工程师系列 之 从前端到后台【最佳实践】
- Bootstrap整合ASP.NET MVC验证、jquery.validate.unobtrusive
- JavaScript数据类型
- Deferred总结
- [BZOJ1823][JSOI2010]满汉全席 做题笔记
- 【JavaScript】JS中String的split()活用
- JSON和JSONP JSONP 实现跨域访问
- HTML学习(一)
- 剑指offer-判断B是不是A的子结构
- 实现倒三角样式
- iOS8后,系统自带BlurEffect 毛玻璃特效
- 操作CString 对象出错 未RealeaseBuffer
- jQuery.extend和jQuery.fn.extend的区别
- 解析json
- [nodejs] 格式化日期、ejs模板引擎改变.ejs为.html、mongoose查询所有