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. The Hundred Greatest Theorems

    The Hundred Greatest Theorems The millenium seemed to spur a lot of people to compile "Top 100& ...

  2. android飞机游戏敌机移动路径

    基础android的飞机类游戏,与前人一样,由surfaceView绘制游戏画面,另起线程控制绘制时间间隔达到动态效果.这里附上最近自己写的敌机自动飞行路径代码.请大家给点意见. 在敌机管理模块,加入 ...

  3. 08重编终极版《东邪西毒:终极版》DVD粤语中字

    1.东邪西毒].Ashes.of.Time.1994.384p.DVDRip.x264.ac3-DTMM.mkv 这个版本最清晰 ,可惜删减了,只有87分钟,粤语,1.4G. 2.东邪西毒(初始版). ...

  4. 修改LiteIDE 编辑窗口的主题

    用习惯了Visual Studio 再看其他编译器总是有点别扭,当然LiteIDE 也是能够自定义主题的,再次感叹作者的用心. 依次: 查看 -> 选项 -> LiteEditor 在编辑 ...

  5. iOS开发——屏幕适配篇&Masonry详解

    Masonry详解 前言 MagicNumber -> autoresizingMask -> autolayout 以上是纯手写代码所经历的关于页面布局的三个时期 在iphone1-ip ...

  6. 运维知识体系v0.5

    http://www.90qj.com/?post=318http://ixdba.blog.51cto.com/2895551/1751377   运维知识体系v0.5-(运维社区-赵班长出品,欢迎 ...

  7. Js_分页

    public ActionResult Index(int? pageIndex) { List<string> data = new List<string>(); ; i ...

  8. Hibernate中SQLite方言

    package com.lain.util; /** * 2013-7-25 * chongzhen_zhao * SQLite方言 */ import java.sql.Types; import ...

  9. 10 Technologies That will Shape Future Education--reference

    http://dizyne.net/technologies-that-will-shape-future-education/ Technology is on the rise and with ...

  10. Java基础知识强化之网络编程笔记14:TCP之多个客户端上传到一个服务器的思考(多线程改进)

    1. 多个客户端上传到一个服务器的思考 通过while循环可以改进一个服务器接收多个客户端. 但是这个是有问题的.如果是这种情况,假设我还有张三,李四,王五这三个人分别执行客户端  张三:好好学习.a ...