私信
administrator
文章
1
评论
0
点赞
5
原创 1
翻译 0
转载 0

文章
关注
粉丝
收藏

个人分类:

简介: 一种线程安全的、可变的字符序列。字符串缓冲区与字符串类似,但可以修改。在任何时候,它都包含一些特定的字符序列,但是序列的长度和内容可以通过某些方法调用来改变。String缓冲区对于多线程来说是安全的。这些方法在必要时是同步的,以便在任何特定实例上的所有操作都以某种串行顺序进行,这种顺序与所涉及的每个单独线程的方法调用顺序一致。StringBuffer上的主要操作是追加和插入方法,它们被重载,以便接受任何类型的数据。 StringBuffer继承关系 ``` public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence ``` StringBuffer构造方法 ``` StringBuffer() 构造一个字符串缓冲区,其中没有字符,初始容量为16个字符。 StringBuffer(CharSequence seq) 构造一个字符串缓冲区,其中包含与指定的CharSequence相同的字符。 StringBuffer(int capacity) 构造一个字符串缓冲区,其中没有字符和指定的初始容量。 StringBuffer(String str) 构造初始化为指定字符串内容的字符串缓冲区。 ``` StringBuffer内部实现原理 以一个简短的例子来分析内部实现机制 ``` StringBuffer sb = new StringBuffer(); Sb.append(123); ``` ``` 由于传入的是int类型,所以内部调用了AbstractStringBuilder的append(int i)方法,如下: public AbstractStringBuilder append(int i) { // 如果传入的值等于Integer的最小值,直接包装为String填充 if (i == Integer.MIN_VALUE) { append("-2147483648"); return this; } // 获取当前追加的长度 int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1 : Integer.stringSize(i); // 当前所需要的容量 int spaceNeeded = count + appendedLength; // 确保char数组的长度足够 ensureCapacityInternal(spaceNeeded); Integer.getChars(i, spaceNeeded, value); count = spaceNeeded; return this; } 数组扩容: // 确保数组长度能容纳追加的数据 private void ensureCapacityInternal(int minimumCapacity) { // 当传入的数据长度加上原有数据长度大于数组长度,需要扩容,扩容后的长度为 // newCapacity(minimumCapacity) if (minimumCapacity - value.length > 0) { // 新建一个数组,长度为newCapacity(minimumCapacity) value = Arrays.copyOf(value, newCapacity(minimumCapacity)); } } // 扩容具体代码 private int newCapacity(int minCapacity) { // 结果为 minCapacity*2+2 int newCapacity = (value.length << 1) + 2; // 如果扩容后小于扩容前的值,则设置为扩容前的值 if (newCapacity - minCapacity < 0) { newCapacity = minCapacity; } // MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8 = 2147483639 // 如果扩容后小于0或者大于MAX_ARRAY_SIZE则设置容量为hugeCapacity(minCapacity) // 否则则设置为minCapacity*2+2 return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0) ? hugeCapacity(minCapacity) : newCapacity; } private int hugeCapacity(int minCapacity) { // 如果当前所需要的容量超过Integer.MAX_VALUE 则抛出OutOfMemoryError() if (Integer.MAX_VALUE - minCapacity < 0) { throw new OutOfMemoryError(); } return (minCapacity > MAX_ARRAY_SIZE) ? minCapacity : MAX_ARRAY_SIZE; } ``` 总结: StringBuffer是一个线程安全的容器,内部的操作方法大部分使用synchronized修饰。它的内部使用数组来实现。每次添加内容的时候都会检查当前添加的内容长度加上已有的内容长度是否大于当前的StringBuffer容量,若大于此容量则进行扩容,扩容的算法为当前容量乘以2加2,数组的最大长度不能超过Integer.MAX_VALUE-8。
阅读 149 评论 0 收藏 0
阅读 149
评论 0
收藏 0


个人信息

账号 : administrator
昵称 :
文章 : 1 篇
关注 : 无
个人网站 :
注册时间 : 2018-06-14
热门文章
最近来访