AbstractStringBuilder是一个抽象类,是StringBuilder和StringBuffer的父类,分析它的源码对StringBuilder和StringBuffer代码的理解有很大的帮助。

先来看看该类的声明:

abstract class AbstractStringBuilder implements Appendable, CharSequence {}

该类实现Appendable和CharSequence接口。

成员变量:

char[] value;//字符数组用来存储字符串
int count;//值是字符串数组被使用的长度。注意,字符数组被使用长度不等于字符数组长度

构造器:

AbstractStringBuilder() {//无参构造器
} AbstractStringBuilder(int capacity) {//带一个int参数构造器,capacity是字符串数组的大小,相当于字符串容器的大小
value = new char[capacity];
}

方法:

//返回字符串实际大小
public int length() {
return count;
}

//返回容器容量
public int capacity() {
return value.length;
}

//确保容器的大小比minimumCapcipty大
public void ensureCapacity(int minimumCapacity) {
if (minimumCapacity > 0)
ensureCapacityInternal(minimumCapacity);
} private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0)//如果minimumCapacity比容器大
expandCapacity(minimumCapacity);//扩容
} void expandCapacity(int minimumCapacity) {
int newCapacity = value.length * 2 + 2;//新容量是(原容量大小+1)*2
if (newCapacity - minimumCapacity < 0)//如果扩容后仍然不够minimumCapacity
newCapacity = minimumCapacity;//那么新容量就是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);
}
}

//设置字符串的长度,如果比原来长,多出来的部分填充'\0',如果比原来短,截断
public void setLength(int newLength) {
if (newLength < 0)
throw new StringIndexOutOfBoundsException(newLength);
ensureCapacityInternal(newLength); if (count < newLength) {
Arrays.fill(value, count, newLength, '\0');
} count = newLength;
}

//返回index位置的字符
public char charAt(int index) {
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
return value[index];
}

//注意下面的append方法,重载的方法很多,支持各种类型参数的append,仅列出部分
//在字符串末尾添加一个字符串,该字符串由obj的toString方法决定
public AbstractStringBuilder append(Object obj) {
return append(String.valueOf(obj));
}

//在字符串末尾添加一个字符串str
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}

//在字符串后面添加null字符串
private AbstractStringBuilder appendNull() {
int c = count;
ensureCapacityInternal(c + 4);
final char[] value = this.value;
value[c++] = 'n';
value[c++] = 'u';
value[c++] = 'l';
value[c++] = 'l';
count = c;
return this;
}

//删除start至end的字符子串,容量不变,字符串长度减少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;
}
}

//返回start至end的子串
public String substring(int start, int end) {
if (start < 0)
throw new StringIndexOutOfBoundsException(start);
if (end > count)
throw new StringIndexOutOfBoundsException(end);
if (start > end)
throw new StringIndexOutOfBoundsException(end - start);
    return new String(value, start, end - start);
}

//在index位置插入str从offset开始,长度为len的子串
public AbstractStringBuilder insert(int index, char[] str, int offset,
int len)
{
if ((index < 0) || (index > length()))
throw new StringIndexOutOfBoundsException(index);
if ((offset < 0) || (len < 0) || (offset > str.length - len))
throw new StringIndexOutOfBoundsException(
"offset " + offset + ", len " + len + ", str.length "
+ str.length);
ensureCapacityInternal(count + len);
System.arraycopy(value, index, value, index + len, count - index);
System.arraycopy(str, offset, value, index, len);
count += len;
}

//将字符串的顺序颠倒,如"abc" reverse 成 "cba"
public AbstractStringBuilder reverse() {
boolean hasSurrogates = false;
int n = count - 1;
for (int j = (n-1) >> 1; j >= 0; j--) {
int k = n - j;
char cj = value[j];
char ck = value[k];
value[j] = ck;
value[k] = cj;
if (Character.isSurrogate(cj) ||
Character.isSurrogate(ck)) {
hasSurrogates = true;
}
}
if (hasSurrogates) {
reverseAllValidSurrogatePairs();
}
return this;
} //...还有其他的方法

可以看到AbstractStringBuilder几乎定义了所有字符串的操作,同时它接受任意类型的拼接,在一个动态数组上操作字符串,对于频繁的字符操作,相比于直接使用String来操作new一个新的String,能提高效率。

java.util.AbstractStringBuilder源码分析的更多相关文章

  1. java.util.HashMap源码分析

    在java jdk8中对HashMap的源码进行了优化,在jdk7中,HashMap处理“碰撞”的时候,都是采用链表来存储,当碰撞的结点很多时,查询时间是O(n). 在jdk8中,HashMap处理“ ...

  2. java.util.Collection源码分析和深度讲解

    写在开头 java.util.Collection 作为Java开发最常用的接口之一,我们经常使用,今天我带大家一起研究一下Collection接口,希望对大家以后的编程以及系统设计能有所帮助,本文所 ...

  3. java.util.Hashtable源码分析

    Hashtable实现一个键值映射的表.任何非null的object可以用作key和value. 为了能存取对象,放在表里的对象必须实现hashCode和equals方法. 一个Hashtable有两 ...

  4. java.util.Dictionary源码分析

    Dictionary是一个抽象类,Hashtable是它的一个子类. 类的声明:/** The <code>Dictionary</code> class is the abs ...

  5. java.util.TreeSet源码分析

    TreeSet是基于TreeMap实现的,元素的顺序取决于元素自身的自然顺序或者在构造时提供的比较器. 对于add,remove,contains操作,保证log(n)的时间复杂度. 因为Set接口的 ...

  6. java.util.TreeMap源码分析

    TreeMap的实现基于红黑树,排列的顺序根据key的大小,或者在创建时提供的比较器,取决于使用哪个构造器. 对于,containsKey,get,put,remove操作,保证时间复杂度为log(n ...

  7. java.util.LinkedList源码分析

    public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, D ...

  8. java.util.ArrayList源码分析

    public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess ...

  9. java.util.HashSet源码分析

    public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java. ...

随机推荐

  1. SAP PP 生产订单变更记录保存

    *&---------------------------------------------------------------------* *& 包括 ZXCO1U01 *&am ...

  2. css3动画属性中的transition属性

    一.语法 transition: property duration timing-function delay; 值 描述 transition-property 规定设置过渡效果的 CSS 属性的 ...

  3. ZZTHX-注意点

    遇到刷卡器加密错误和后台解密不了的问题确实不太好解决,也有加密后的数据返回,可是后台总是解密不了.在这里我首先要感谢一下我的同事,在他们的帮助下,项目顺利完成了.有以下注意点现汇总如下: 1.密码加密 ...

  4. POJ3273-Monthly Expense (最小化最大值)

    题目链接:cid=80117#problem/E">click here~~ [题目大意] 农夫JF在n天中每天的花费,要求把这n天分作m组.每组的天数必定是连续的.要求分得各组的花费 ...

  5. 手把手教你Android来去电通话自动录音的方法

    我们在使用Android手机打电话时,有时可能会需要对来去电通话自动录音,本文就详细讲解实现Android来去电通话自动录音的方法,大家按照文中的方法编写程序就可以完成此功能. 来去电自动录音的关键在 ...

  6. [Effective C++ --007]为多态基类声明virtual析构函数

    引言: 我们都知道类的一个很明显的特性是多态,比如我们声明一个水果的基类: class Fruit { public: Fruit() {}; ~Fruit(){}; } 那么我们根据这个Fruit基 ...

  7. 取得root权限后怎么删除程序

    不知道这个算什么教程,随便一个分类吧,管理员不要扣我分啊,我也是为大家服务嘛,不对的话可以帮我处理下) 最近也学习了下,把我的X8(国行2.1版)给root了,怎么root,论坛里有很多帖子,这里就不 ...

  8. Mybatis案例

    MyBatis MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架. MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及对结果集的检索. MyBatis 可 ...

  9. mysql:错误日志log_error:

    1.启动错误日志: 在不同的情况下,错误日志会记录在不同的位置,如果没有配置文件指定文件名,则默认为hostname.err 在mysql5.6的RPM发布的方式中,错误日志被放在/var/log/m ...

  10. Linux上安装Redmine

    安装基本的软件环境 # yum install zip unzip libyaml-devel zlib-devel curl-devel openssl-devel httpd-devel apr- ...