可分迭代器java
package com.example.demo.split; import java.util.Spliterator; import java.util.function.Consumer; import java.util.stream.IntStream; import java.util.stream.Stream; import java.util.stream.StreamSupport; public class SplitTest { static class WordCounter { private final int counter; private final boolean lastSpace; public WordCounter(int counter, boolean lastSpace) { this.counter = counter; this.lastSpace = lastSpace; } public WordCounter accumulate(Character c) { if (Character.isWhitespace(c)) { return lastSpace ? this : new WordCounter(counter, true); } return lastSpace ? new WordCounter(counter + 1, false) : this; //上一次空格,此次不是就加1 } /** * 把兩個計數器累加起來 * * @param wordCounter * @return */ public WordCounter combine(WordCounter wordCounter) { return new WordCounter(counter + wordCounter.counter, wordCounter.lastSpace); } public int getCounter() { return counter; } public boolean isLastSpace() { return lastSpace; } } /** * 自定義拆分 */ static class WordCounterSpliterator implements Spliterator<Character> { private final String string; private int currentChart = 0; public WordCounterSpliterator(String string) { this.string = string; } @Override public boolean tryAdvance(Consumer<? super Character> consumer) { consumer.accept(string.charAt(currentChart++)); return currentChart < string.length(); } /** * 拆分邏輯 <br> * 若是返回 null 表示要解析的string 已經足夠小,能夠順序處理了 * * @return */ @Override public Spliterator<Character> trySplit() { int currentSize = string.length() - currentChart; if (currentSize < 10) { return null; } // 必須以空格作爲拆分點 for (int splitPos = currentSize / 2 + currentChart; splitPos < string.length(); splitPos++) { if (Character.isWhitespace(string.charAt(splitPos))) { Spliterator<Character> spliterator = new WordCounterSpliterator(string.substring(currentChart, splitPos)); currentChart = splitPos; return spliterator; } } return null; } @Override public long estimateSize() { return string.length() - currentChart; } @Override public int characteristics() { return ORDERED + SIZED + SUBSIZED + NONNULL + IMMUTABLE; } } static int count(Stream<Character> stream) { WordCounter wordCounter = stream.reduce(new WordCounter(0, true), WordCounter::accumulate, WordCounter::combine); return wordCounter.getCounter(); } public static void main(String[] args) { String words = "Nel mezzo del camin di nostra vita" + " mi ritrovai in una selva oscura che la dritta via era smarrita"; Spliterator<Character> spliterator = new WordCounterSpliterator(words); Stream<Character> stream = IntStream.range(0, words.length()) .mapToObj(words::charAt); int count = count(stream); System.out.println("1單詞數量爲:" + count); Stream<Character> stream2 = StreamSupport.stream(spliterator, true); int count2 = count(stream2); System.out.println("[單詞數量爲]:" + count2); } }