一、基本认识
CharSequence是java.lang包下的一个接口,此接口对应不同的实现类,如CharBuffer、String、StringBuffer、StringBuilder
CharSequence接口的源码
package java.lang;
import java.util.NoSuchElementException;
import java.util.PrimitiveIterator;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.IntConsumer;
import java.util.stream.IntStream;
import java.util.stream.StreamSupport;
public interface CharSequence {
int length();
char charAt(int index);
CharSequence subSequence(int start, int end);
public String toString();
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);
}
}
二、基本注意事项
对于抽象类或者接口来说不可以直接使用new的方式创建对象,但是可以直接给它赋值;
例如:CharSequence b = "test" 是一个类型强转操作 等于CharSequence b = (CharSequence) new String("test")
三、学习和理解
3.1 在线文档
3.2 理解注意
a-释义理解
在"可读序列"中有这么一句话,读时有所疑惑,所以在这里拿出来再做说明,
"此接口不修改 equals 和 hashCode 方法的常规协定。因此,通常未定义比较实现 CharSequence 的两个对象的结果。
每个对象都可以通过一个不同的类实现,而且不能保证每个类能够测试其实例与其他类的实例的相等性。
因此,使用任意 CharSequence 实例作为集合中的元素或映射中的键是不合适的。"
`理解`:
我们在字符序列中使用equals()往往只希望比对字符序列内容,而非是对象'引用地址(通过hashcode)',
但是CharSequence并没有重写equals(),所以如果我们通过多态将CharSequence的'实现类对象向上转型'为接口,
那么此时再使用equals(),'如果是同一个类的对象那么比对是通过该类重写的equals(),
若不是同一个对象,那么是通过Object的equals方法来比对(通过hashcode)',
而不是字符序列内容,即便两个实现类重写了equals().举例如下:
b-举例1
b-举例2
参考文章: