簡體   English   中英

Java 8:如何創建java.util.stream.Stream <Character> 基於java.io.Reader

[英]Java 8: How to create java.util.stream.Stream<Character> based on java.io.Reader

閱讀Java 8文檔時,似乎原本打算使用java.util.stream.Stream的對象可能最終由I / O java.io.InputStream支持。

因此,我想讀取一個字符流,並使用新功能將其輸入到map-reduce管道中。 我找不到任何實用程序方法來執行此操作,因此我不得不自己動手:

public static Stream<Character> charStream(Reader r) {
    Iterator<Character> iter = new Iterator<Character>() {
        Character nextChar = null;

        @Override
        public boolean hasNext() {
            if (nextChar != null) {
                return true;
            } else {
                try {
                    int readChar = r.read();
                    if(readChar == -1) { 
                        return false;
                    }
                    nextChar = Character.valueOf((char) readChar);
                    return true;
                } catch (IOException e) {
                    throw new UncheckedIOException(e);
                }
            }
        }

        @Override
        public Character next() {
            if (nextChar != null || hasNext()) {
                Character theChar = nextChar;
                nextChar = null;
                return theChar;
            } else {
                throw new NoSuchElementException();
            }
        }
    };
    return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
            iter, Spliterator.ORDERED | Spliterator.NONNULL), false);
}

是否有可以實現相同或相似作用的實用方法?

我發現在這種情況下,實現Spliterator而不是Iterator更加容易:

public static IntStream charStream(Reader r) {
    Spliterator.OfInt split = new Spliterators.AbstractIntSpliterator(Long.MAX_VALUE, Spliterator.ORDERED) {
        @Override
        public boolean tryAdvance(IntConsumer action) {
            try {
                int c = r.read();
                if (c == -1) {
                    return false;
                } else {
                    action.accept(c);
                    return true;
                }
            } catch (IOException ex) {
                throw new UncheckedIOException(ex);
            }
        }
    };

    return StreamSupport.intStream(split, false);
}

最好實現一個IntStream以避免裝箱。 您始終可以使用.mapToObj(i->(char) i)IntStream轉換為Stream<Character>

您可以使用以下方式創建表示字符的IntStream

new BufferedReader(r).lines().flatMapToInt(CharSequence::chars)

如果真的必須是一個(拳擊) Stream<Character>你可以使用mapToObj(c -> (char)c)IntStream

public static Stream<Character> chars(Reader r) {
    return new BufferedReader(r).lines().flatMapToInt(CharSequence::chars)
      .mapToObj(c -> (char)c);
}

但在大多數情況下

public static IntStream chars(Reader r) {
    return new BufferedReader(r).lines().flatMapToInt(CharSequence::chars);
}

應該足夠了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM