2016-05-27 40 views
1

私はBufferedReaderlines()メソッドがSpliterator<T>の代わりにIterator<T>インターフェイスの実装でStream<T>のインスタンスを作成することに驚きました。多くの理由から、たとえ並列性がなくても、Spliterator<T>を使用するといくつかの利点があります。例えば、質問Iterator versus Stream of Java 8からBrian Goetz states in its answerなぜBufferedReader :: lines()は、Spliterator <T>ではなく、<T>のイテレータ<T>を作成しますか?

Spliteratorでも順次、Iteratorより根本的に低く要素ごとのアクセスコストを持っています。

は、なぜBufferedReader::lines()Iterator<T>代わりのSpliterator<T>Stream<T>を作成しますか?

+0

人はよく知っているものを使います。 JRE開発者が異なる必要がある理由はありません。 – Holger

+0

IMHO新しいJDK8 APIに密接に関連する新機能、特に 'Stream 'を開発しているJRE開発者は、これを認識する必要があります。 –

+0

これは私の心にもつながっています。特に、最近のJava 9の新しい方法については、Spliteratorの利点が広く知られるようになりました。それでも、私はあまりにも速く判断しないように最善を尽くしています。私たちは、特定の開発者がそのような方法を実装した日を処理しなければならない作業量について知りません... – Holger

答えて

4

Iteratorを使用して実装する技術的理由はありません。 Brian Goetzの声明はまだ成立している。なぜなら、この具体的なケースでパフォーマンスの違いが気づかない理由は、ベースの実装は、覚えておくべき状態を維持しなければならない反復子の実装とは対照的に、readLine()を呼び出すtryAdvanceメソッドの実装ですhasNext()が既に呼び出されていて、その結果が返されているかどうか。

実際の理由は同じ理由です。なぜここに多くの開発者がそれを行っているのですか?イテレータはよく知られているので、開発者はすぐにそれを実装し実装します(以前の回答でも同様でした)。 JRE開発の場合、歴史的な理由がある可能性があります。 Spliteratorが導入され、その後にリファクタリングされる前に実装されていたことを示します。

String.chars()のような悪意のある犯罪者が存在します。これは、完璧な並列サポートを備えた、高速で軽量のアレイベースのスプライテータとして実装できます。その代わりに、Java 8のPrimitiveIterator.OfIntベースの実装をJava 8で使用すると、より複雑で、パフォーマンスが無駄になり、本質的にパラレル・サポートが貧弱です(基礎実装はバッファー)。

ありがたいことに、String.chars()はJava 9で修正される予定です。これは、関係するすべての開発者がメッセージを受け取ったことを意味するものではありません。私はちょうどJava 9で導入されたMatcher.results()を見ており、Scanner.findAllとは対照的に、肯定的な例を挙げると、Iteratorの迂回経路も使用しています。もちろん、これはすべてリリース前に変更される可能性があります。

しかし、Stream製造方法で不必要なIterator迂回路はすぐに消えそうにありません。場合によっては、メソッドを書き直す時間を無駄にすることもありません。

関連する問題