java 8 Spliterator 自定義

可分迭代器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);
    }


}
相關文章
相關標籤/搜索