接口 Appendable
public interface Appendable {
Appendable append(char c) throws IOException; //1
Appendable append(CharSequence csq, int start, int end) throws IOException;//2
}
接口 CharSequence
java8新增2个default方法
String AbstractStringBuilder StringBuffer StringBuilder 均实现了CharSequence
疑点:AbstractStringBuilder 是StringBuffer StringBuilder的父类,已经父类已经实现了接口
CharSequence
StringBuffer StringBuilder 本应不必要在实现接口 ,有声明实现接口
CharSequence
的必要性是?(个人见解) 为了显示的说明 StringBuffer StringBuilder也实现接口
CharSequence
default 修饰接口内的方法后 该方法可以具体实现
public interface CharSequence {
int length();
char charAt(int index);
CharSequence subSequence(int start, int end);
public String toString()
public default IntStream chars() //省略其实现
public default IntStream codePoints()//省略其实现
//分别转换为以char和codepoint为单位的java stream.注意转换后为int类型的unicode编码.
}
抽象类 AbstractStringBuilder
StringBuffer 和 StringBuilder 继承的抽象类 AbstractStringBuilder
AbstractStringBuilder类完成了 维护可变数组的实现 其中所有方法均为实例方法
abstract class AbstractStringBuilder implements Appendable, CharSequence { char[] value; int count; //数组内实际的存储的长度 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; //构造函数见下表格 ...
与实现可变数组功能相关的方法
public void ensureCapacity(int minimumCapacity) { if (minimumCapacity > 0) ensureCapacityInternal(minimumCapacity); } //实现数组空间处理的 三个私有方法 private void ensureCapacityInternal(int minimumCapacity) { //实际执行扩容的方法 // overflow-conscious code 疑问: 为何不与count比较? 为减少更新容量的范围 所以与更大一些的 value.length 相比 if (minimumCapacity - value.length > 0) { //参数 大于 当前字符串容量 则扩展到参数大小的字符数组 value = Arrays.copyOf(value, newCapacity(minimumCapacity)); } } //两个判断扩展后的容量的最小值该为多少 private int newCapacity(int minCapacity) { // // overflow-conscious code int newCapacity = (value.length << 1) + 2; //为什么 +2 if (newCapacity - minCapacity < 0) { newCapacity = minCapacity; } return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0) ? hugeCapacity(minCapacity) : newCapacity; } private int hugeCapacity(int minCapacity) { //实际允许的最大容量是Integer.MAX_VALUE if (Integer.MAX_VALUE - minCapacity < 0) { // overflow throw new OutOfMemoryError(); } return (minCapacity > MAX_ARRAY_SIZE) // MAX_ARRAY_SIZE为类中常量 其值为Integer.Max_VALUE - 8 (VM可能需要在数组头部存储信息 所以 减去8) ? minCapacity : MAX_ARRAY_SIZE; }
public int capacity() { //查看字符数组的容量 return value.length; } public int length() { //查看字符数组的已使用的长度 return count; }
增 append public AbstractStringBuilder return 语句 append(Object obj) append(String.valueOf(obj)); append(String s) if (s == null) return appendNull();//私有方法用于处理 添加"null"
int len = s.length();
ensureCapacityInternal(count + len);
sb.getChars(0, len, value, count);//在当
count += len;
return this;append(StringBuffer s) (缺省) append(AbstractStringBuilder s ) append(CharSequence s) 覆盖Appendable接口的append方法1 用instanceof 判断类型在调用其他append方法 append(CharSequence s, int start, int end) 覆盖Appendable接口的append方法2 append(char[] str) append(char str[], int offset, int len) append(xxx)
//xxx: (除short和byte的基本类型)
appendCodePoint(int codePoint) public AbstractStringBuilder
删
delete(int start, int end) deleteCharAt(int index) System.arraycopy(value, index+1, value, index, count-index-1); count--; 改
public void
setLength(int newLength)
作用: 将目前已经用了的长度(即count)更改为 参数大小
参数要求: 必须大于等于0
若newLength大于当前实际容量,则容量将扩展到参数大小
字符数组的 [原count , newLength)范围内填充'\0' (空字符)
public void setCharAt
(int index, char ch)
作用:将字符数组中指定下标的元素替换
注意: 仅允许替换 [0, count) 部分的下标
(public) insert
insert(xxx)//xxx: (除short和byte的基本类型)
insert
(int offset, char[] str)
例如 在abcde 在下标2处插入某字符数组str ->ab[str]cde
确保内部容量 ensureCapacityInternal(count + str.length)
利用System.arraycopy()方法进行两次复制
第一次复制:插入位置之后的子串 cde
第二次复制:用str填充 第一次复制时原字符串之间的空白
insert(int index, char[] str, int offset, int len)
insert(int offset, String str) insert(int offset, Object obj) insert(int dstOffset, CharSequence s) insert(int dstOffset, CharSequence s, int start, int end) public AbstractStringBuilder replace(int start, int end, String str) 查
查长度 / 查容量 Length() /Capacity() 以下标 查 字符 char charAt(int index) 注意: 仅允许替换 [0, count) 部分的下标 (public)indexOf int indexOf ( String str ) int indexOf (String str, int fromIndex) int lastIndexOf(String str) int lastIndexOf(String str, int fromIndex){
return String.indexOf(value, 0, count, str, fromIndex); }对应下标元素的代码点 返回指定下标处的代码点 int codePointAt(int index) int codePointBefore(int index) int codePointCount(int beginIndex, int endIndex) int offsetByCodePoints(int index, int codePointOffset) void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
转换 public void trimToSize() 去掉字符数组中未用到的空间 取子串 public String substring(int start) public String substring (int start, int end)
public CharSequence subSequence(int start, int end) 反转 public AbstractStringBuilder reverse() public void trimToSize() { //去掉字符数组中多余空间 if (count < value.length) { value = Arrays.copyOf(value, count); } } public AbstractStringBuilder reverse() { boolean hasSurrogates = false; int n = count - 1; //下标范围 0 - 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语句判断 已交换的字符是否为补增字符集 若为补增字符集 翻转前:高代理 低代理->低代理 高代理 (顺序已错误错误) if (Character.isSurrogate(cj) || Character.isSurrogate(ck)) { hasSurrogates = true; } } if (hasSurrogates) { //(将已调换造成错误顺序的)补增字符 调换正确 reverseAllValidSurrogatePairs();// 低代理 高代理->高代理 低代理 } return this; }
AbstractStringBuilder StringBuffer StringBuilder 构造函数 AbstractStringBuilder() { } public StringBuffer() { super(16);} public StringBuilder() { super(16); } AbstractStringBuilder(int capacity) {
value = new char[capacity]; }public StringBuffer(int capacity) {
super(capacity);. }public StringBuilder(int capacity) {
super(capacity); }public XX(String str) { super(str.length() + 16); append(str); } public XX( CharSequence
seq) { this(seq.length() + 16); append(seq); }
StringBuilder这个类的设计用途是作为一个临时替代 用于单个线程 主要应用 append 和 insert方法