Java源码赏析(六)Java String 三顾
在大致了解了String之后,可能有的读者发现了,我们并没有谈到CharSequence接口。
原因是在这一节,CharSequence要和StringBuilder(Java1.5)、StringBuffer(Java1.0)一起讨论。
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); /** * 转化为String */ public String toString(); /** * 转化为int流 */ 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); } /** * 转化为int流 */ 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); } }
chars、codePoints是Java8的新增方法,主要用于int流操作,下面举个例子
//判断字符序列是否存在空格 boolean containsWhitespaces(CharSequence actual) { return actual.chars().anyMatch(Character::isWhitespace); } //判断字符序列不为空,而且存在空格 public static boolean containsWhitespace(String str) { return Objects.nonNull(str) && str.codePoints().anyMatch(Character::isWhitespace); }
StringBuffer(线程安全)和StringBuilder(线程不安全)都是可变字符串
未完待续
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步