目录
一:CharSequence类简介
是java.lang包下的一个接口,此接口对多种不同的对char访问的统一接口,像String、StringBuffer、StringBuilder类都是CharSequence的子接口;
CharSequence类和String类都可以定义字符串,但是String定义的字符串只能读,CharSequence定义的字符串是可读可写的;对于抽象类或者接口来说不可以直接使用new的方式创建对象,但是可以直接给它赋值;
CharSequence b = "s";
CharSequence b = "s" 是一个类型强转操作 等于CharSequence b = (CharSequence) new String("s")
二 :应用举例
例如在常用的判断字符串是否为空的方法中,利用CharSequence类代替String,可以做到连同char、string等不同CharSequence的子接口的判空判断:
public static boolean isEmpty(final CharSequence s) {
return s == null || s.length() == 0;
}
三:CharSequence接口的源码:
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 {
/**
* 返回此字符序列的长度。该长度是序列中的 16 位 char 数.
* @return 此序列中的 char 数
*/
int length();
/**
*
* 返回指定索引处的char值。
* @param index 要返回的 char 值的索引
*
* @return 指定的Char值
*
* @throws IndexOutOfBoundsException
* 如果 index 参数为负或不小于 length()
*/
char charAt(int index);
/**
* 返回一个新的 CharSequence,它是此序列的子序列。子序列从指定序列的 char 值开始,并
* 在索引 end - 1 的 char 值结束。返回序列的长度(char 中)是 end - start,因此,
* 如果 start == end,则返回一个空序列。
*
* @param start 开始索引(包括)
* @param end 结束索引(不包括)
*
* @return 指定的子序列
*
* @throws IndexOutOfBoundsException
* 如果 start 或 end 为负,end 大于 length() 或者 start 大于 end
*/
CharSequence subSequence(int start, int end);
/**
* 返回一个包含此序列中字符的字符串,该字符串与此序列的顺序相同。
* 字符串的长度就是此序列的长度。
* 覆盖: 类 Object 中的 toString
* @return 一个完全由此序列的字符组成的字符串
*/
public String toString();
/**
* 返回一个从这个序列中值为零扩展的字符值的流。
* 映射到代理代码点的任何字符都将通过未解释的方式传递。
* 如果在读取流时发生了突变,则结果是未定义的。
*
* @return 从这个序列的IntStream字符值
* @since 1.8
*/
public default IntStream chars() {
class CharIterator implements PrimitiveIterator.OfInt {
int cur = 0;
//如果迭代器中还有元素,则返回true。
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));
}
}
}
// 返回一个通过继承了Spliterator.OfInt的Supplier 创建的新的顺序或并行IntStream 。
return StreamSupport.intStream(() ->
Spliterators.spliterator(
new CharIterator(),
length(),
Spliterator.ORDERED),
Spliterator.SUBSIZED | Spliterator.SIZED | Spliterator.ORDERED,
false);
}
/**
* 从这个序列返回一个代码点值流。在序列中遇到的任何代理对都是按字符组合的。
* toCodePoint和结果被传递到流。任何其他代码单元,
* 包括普通的BMP字符、未配对的代理和未定义的代码单元,都是零扩展到int值,
* 然后将这些值传递给流。 如果在读取流时发生了突变,则结果是未定义的。
*
* @return 从这个序列中输入的Unicode代码点。
* @since 1.8
*/
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;
}
}
//如果迭代器中还有元素,则返回true。
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;
}
}
// 返回一个通过继承了Spliterator.OfInt的Supplier 创建的新的顺序或并行IntStream 。
return StreamSupport.intStream(() ->
Spliterators.spliteratorUnknownSize(
new CodePointIterator(),
Spliterator.ORDERED),
Spliterator.ORDERED,
false);
}
}
参考:
https://blog.youkuaiyun.com/yaomingyang/article/details/79253470
https://blog.youkuaiyun.com/a_man_floats/article/details/79141466