前言
**上一篇,我们正式提及到String类到不可修改性,所以用String类进行字符串到多次拼接,存在有效率问题。于是在JDK1.0的时候就推出了StringBuffer类,该类是线程安全的。**
1、StringBuffer类的定义
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
首先根据类定义,我们可以看到StringBuffer类继承于AbstractStringBuilder类,同时实现类两个接口,java.io.Serializable为序列化接口(该接口表示类可以被序列化到能力,是一个空接口),CharSquence(字符序列接口,定义了字符串都会用到到方法)
2、CharSquence接口
CharSquence接口是String、StringBuilder、StringBuffer都有实现都接口之一,我们先看看该接口给我们提供了哪些操作标准。
从代码都注释上可以看到事实上,CharSequence接口是在JDK1.4到时候才有到,而StringBuffer是1.0到时候就有,JDK开发人员对String、StringBuffer、StringBuidler类做了一次重构,抽取公共方法提供了这样一个接口。
/** 省略部分注释
* @author Mike McCloskey
* @since 1.4
* @spec JSR-51
*/
public interface CharSequence {
int length(); //取得字符串序列的长度
char charAt(int index); //返回指定索引的字符,索引返回为0-length()-1,如果不再范围内,将抛出一个异常(索引越界异常)IndexOutOfBoundsException
//根据给定起始索引和结束索引,获取字符串序列的子序列,同样会抛出索引越界异常
CharSequence subSequence(int start, int end);
// 返回String 类对象,字符串于原来字符串一样
public String toString();
// 这是CharSquence接口的默认方法,JDK1.8的特性,旨在接口中提供所有子类的默认实现
public default IntStream chars() {
class CharIterator implements PrimitiveIterator.OfInt {
int cur = 0;
public boolean hasNext() {
return cur < length();
}
public int nextInt() {
if (hasNext()) {
return charAt(cur++);
} else {
throw new NoSuchElementException();
}
}
@Override
public void forEachRemaining(IntConsumer block) {
for (; cur < length(); cur++) {
block.accept(charAt(cur));
}
}
}
return StreamSupport.intStream(() ->
Spliterators.spliterator(
new CharIterator(),
length(),
Spliterator.ORDERED),
Spliterator.SUBSIZED | Spliterator.SIZED | Spliterator.ORDERED,
false);
}
public default IntStream codePoints() {
class CodePointIterator implements PrimitiveIterator.OfInt {
int cur = 0;
@Override
public void forEachRemaining(IntConsumer block) {
final int length = length();
int i = cur;
try {
while (i < length) {
char c1 = charAt(i++);
if (!Character.isHighSurrogate(c1) || i >= length) {
block.accept(c1);
} else {
char c2 = charAt(i);
if (Character.isLowSurrogate(c2)) {
i++;
block.accept(Character.toCodePoint(c1, c2));
} else {
block.accept(c1);
}
}
}
} finally {
cur = i;
}
}
public boolean hasNext() {
return cur < length();
}
public int nextInt() {
final int length = length();
if (cur >= length) {
throw new NoSuchElementException();
}
char c1 = charAt(cur++);
if (Character.isHighSurrogate(c1) && cur < length) {
char c2 = charAt(cur);
if (Character.isLowSurrogate(c2)) {
cur++;
return Character.toCodePoint(c1, c2);
}
}
return c1;
}
}
return StreamSupport.intStream(() ->
Spliterators.spliteratorUnknownSize(
new CodePointIterator(),
Spliterator.ORDERED),
Spliterator.ORDERED,
false);
}
}