深入学习java源码之CharSequence.chars()CharSequence.codePoints()

String 是java中的字符串,它继承于CharSequence。
String类所包含的API接口非常多。为了便于今后的使用,我对String的API进行了分类,并都给出的演示程序。

String 和 CharSequence 关系
String 继承于CharSequence,也就是说String也是CharSequence类型。
CharSequence是一个接口,它只包括length(), charAt(int index), subSequence(int start, int end)这几个API接口。除了String实现了CharSequence之外,StringBuffer和StringBuilder也实现了CharSequence接口。
需要说明的是,CharSequence就是字符序列,String, StringBuilder和StringBuffer本质上都是通过字符数组实现的!

​​StringBuilder ​​和 StringBuffer 的区别

​​StringBuilder ​​和 ​​StringBuffer​​都是可变的字符序列。它们都继承于​​AbstractStringBuilder​​,实现了CharSequence接口。
但是,StringBuilder是非线程安全的,而StringBuffer是线程安全的。

深入学习java源码之CharSequence.chars()CharSequence.codePoints()_System

charSequence是一个接口,表示char值的一个可读序列。此接口对许多不同种类的char序列提供统一的自读访问。此接口不修改该equals和hashCode方法的常规协定,因此,通常未定义比较实现 CharSequence 的两个对象的结果。他有几个实现类:CharBuffer、String、StringBuffer、StringBuilder。

java8新增2个default方法

public default IntStream chars()
public default IntStream codePoints()

分别转换为以char和codepoint为单位的java stream.注意转换后为​​int​​类型的unicode编码.

函数式接口Consumer

package jdk8;

import java.util.function.Consumer;

public class ConsumerTest {

public static void main(String[] args) {
testConsumer();
testAndThen();
}

/**
* 一个简单的平方计算
*/
public static void testConsumer(){
Consumer<Integer> square = x -> System.out.println("print square : " + x * x);
square.accept(2);
}

/**
* 定义3个Consumer并按顺序进行调用andThen方法,其中consumer2抛出NullPointerException。
*/
public static void testAndThen(){
Consumer<Integer> consumer1 = x -> System.out.println("first x : " + x);
Consumer<Integer> consumer2 = x -> {
System.out.println("second x : " + x);
throw new NullPointerException("throw exception test");
};
Consumer<Integer> consumer3 = x -> System.out.println("third x : " + x);

consumer1.andThen(consumer2).andThen(consumer3).accept(1);
}
}

下面是执行结果:

print square : 4

first x : 1
second x : 1
Exception in thread "main" java.lang.NullPointerException: throw exception test
at jdk8.ConsumerTest.lambda$testAndThen$2(ConsumerTest.java:27)
at java.util.function.Consumer.lambda$andThen$0(Consumer.java:65)
at java.util.function.Consumer.lambda$andThen$0(Consumer.java:65)
at jdk8.ConsumerTest.testAndThen(ConsumerTest.java:31)
at jdk8.ConsumerTest.main(ConsumerTest.java:9)

Process finished with exit code 1

在testAndThen()方法的执行结果可以看到打印的顺序和出现异常的情况(third x : 1 并没有输出)

foreach

default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}

Consumer的accept只接受一个参数,那如果要是想使用多个参数要怎么办?jdk8又提供了一个BiConsumer接口类,该类与Consumer的区别是可以接受2个参数。

深入学习java源码之CharSequence.chars()CharSequence.codePoints()_System_02

 

java源码

Modifier and Type

Method and Description

​char​

​charAt(int index)​

返回 ​​char​​指定索引处的值。

​default IntStream​

​chars()​

返回一个 ​​int​​​的流,从这个序列中零扩展 ​​char​​值。

​default IntStream​

​codePoints()​

从此序列返回码流值。

​int​

​length()​

返回此字符序列的长度。

​CharSequence​

​subSequence(int start, int end)​

返回一个 ​​CharSequence​​ ,这是这个序列的一个子序列。

​String​

​toString()​

以与此顺序相同的顺序返回包含此序列中的字符的字符串。

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);
}
}

 

Modifier and Type

Method and Description

​void​

​forEachRemaining(T_CONS​

对每个剩余的元素执行给定的动作,按照迭代时发生的顺序,直到所有元素都被处理或动作引发异常。

package java.util;

import java.util.function.Consumer;
import java.util.function.DoubleConsumer;
import java.util.function.IntConsumer;
import java.util.function.LongConsumer;


public interface PrimitiveIterator<T, T_CONS> extends Iterator<T> {

@SuppressWarnings("overloads")
void forEachRemaining(T_CONS action);

/**
* An Iterator specialized for {@code int} values.
* @since 1.8
*/
public static interface OfInt extends PrimitiveIterator<Integer, IntConsumer> {

int nextInt();

default void forEachRemaining(IntConsumer action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(nextInt());
}

@Override
default Integer next() {
if (Tripwire.ENABLED)
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfInt.nextInt()");
return nextInt();
}

@Override
default void forEachRemaining(Consumer<? super Integer> action) {
if (action instanceof IntConsumer) {
forEachRemaining((IntConsumer) action);
}
else {
// The method reference action::accept is never null
Objects.requireNonNull(action);
if (Tripwire.ENABLED)
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfInt.forEachRemainingInt(action::accept)");
forEachRemaining((IntConsumer) action::accept);
}
}

}


public static interface OfLong extends PrimitiveIterator<Long, LongConsumer> {


long nextLong();

default void forEachRemaining(LongConsumer action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(nextLong());
}

@Override
default Long next() {
if (Tripwire.ENABLED)
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfLong.nextLong()");
return nextLong();
}

@Override
default void forEachRemaining(Consumer<? super Long> action) {
if (action instanceof LongConsumer) {
forEachRemaining((LongConsumer) action);
}
else {
// The method reference action::accept is never null
Objects.requireNonNull(action);
if (Tripwire.ENABLED)
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfLong.forEachRemainingLong(action::accept)");
forEachRemaining((LongConsumer) action::accept);
}
}
}


public static interface OfDouble extends PrimitiveIterator<Double, DoubleConsumer> {


double nextDouble();

default void forEachRemaining(DoubleConsumer action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(nextDouble());
}

@Override
default Double next() {
if (Tripwire.ENABLED)
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfDouble.nextLong()");
return nextDouble();
}

@Override
default void forEachRemaining(Consumer<? super Double> action) {
if (action instanceof DoubleConsumer) {
forEachRemaining((DoubleConsumer) action);
}
else {
// The method reference action::accept is never null
Objects.requireNonNull(action);
if (Tripwire.ENABLED)
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfDouble.forEachRemainingDouble(action::accept)");
forEachRemaining((DoubleConsumer) action::accept);
}
}
}
}

函数式接口

package java.util.function;
import java.util.Objects;


@FunctionalInterface
public interface Consumer<T> {


void accept(T t);


default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}

 

package java.util.function;
import java.util.Objects;

@FunctionalInterface
public interface DoubleConsumer {

void accept(double value);

default DoubleConsumer andThen(DoubleConsumer after) {
Objects.requireNonNull(after);
return (double t) -> { accept(t); after.accept(t); };
}
}

 

 

package java.util.function;
import java.util.Objects;


@FunctionalInterface
public interface IntConsumer {


void accept(int value);

default IntConsumer andThen(IntConsumer after) {
Objects.requireNonNull(after);
return (int t) -> { accept(t); after.accept(t); };
}
}

 

package java.util.function;
import java.util.Objects;


@FunctionalInterface
public interface LongConsumer {

void accept(long value);

default LongConsumer andThen(LongConsumer after) {
Objects.requireNonNull(after);
return (long t) -> { accept(t); after.accept(t); };
}
}

 

package java.util;
import java.util.function.Consumer;

public interface Iterator<E> {

boolean hasNext();

E next();

default void remove() {
throw new UnsupportedOperationException("remove");
}

default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
}