5

Streamインターフェイスには、メソッドof()の2つのオーバーロードがあります。これらのうちの1つは可変アライメント方式であり、もう1つは単一の引数を取ります。なぜJavaストリームインターフェイスで()のvarargsメソッドをオーバーロードするのですか?

単一引数の方法は、1つの引数を可変式方法に渡すよりパフォーマンスの最適化ですか?もしそうなら、それはどのように性能を改善するのですか? empty()メソッドについても同様の質問が出る可能性があります。これは、可変アライメントof()を囲むシンタックスシュガーと思われます。

具体的にはSpliteratorがどのようにインスタンス化されているかの違いによって、実装がこれらのメソッド間で異なることがわかります。 Stream APIにはどのような利点がありますか?

答えて

5

はい、varargsバージョンを使用した場合の1つの要素だけを保持する配列を作成するオーバーヘッドを避けるための最適化です。

同じ質問 は、あなたが見ている()

何実装のバージョンの可変アリティ周りのシンタックスシュガーであるように見えるだろう、空()メソッドの尋ねられるだろうか?実装を見ると、私はこれを見ません。

+0

私は、メソッドシグネチャがシンタックスシュガーを示すように見えることを意味していました(ドキュメントはどちらか一方を指していません)。実装が異なることがわかります。 – jaco0646

+0

単一要素または空の配列の回避は、マイクロ最適化のように思えます。これは平均的な開発者が気にするべきものなのでしょうか?私はすべての私のvarargsメソッドのこのタイプのパフォーマンス最適化を提供する必要がありますか? – jaco0646

+1

@ jaco0646、構文砂糖には何が問題なのですか?特に、パフォーマンスの最適化の機会を提供している場合は特にそうです。 –

5

空のストリームと単一のストリームは、特に.flatMap()を使用する場合によく使用されます。例えば、ここでのJava-9でimplementedがいかにOptional.stream()です:

public Stream<T> stream() { 
    if (!isPresent()) { 
     return Stream.empty(); 
    } else { 
     return Stream.of(value); 
    } 
} 

のでOptionalsのストリームを与え、あなたはフラットな流れの中に、このようにそれらのラップを解除することができます:ここで

streamOfOptionals.flatMap(Optional::stream); 

あなたは空のトンを作成しますストリームだけでなく、単一の要素のストリーム、そのようなケースを最適化するので非常に合理的に見えます。特にStream.empty()Stream.of()と異なり、空の配列を作成せず、スプライテータを作成しません(同じスプライテータインスタンスを再利用します)。 Stream.of(T)も特にStreamBuilderImpl内で最適化されているため、1つの要素に対して配列は割り当てられません。

1

この質問に対する以前の回答:JEP 269: Convenience Factory Methods for Collectionsを確認した公式のリソースを見つけました。その提案の説明は、

は、これらのコレクションの変更不可能なインスタンスを作成するため ListSet、及び Mapインターフェイス上の静的ファクトリメソッドを提供することです。

これらには可変長オーバーロードが含まれているため、コレクションサイズに一定の制限はありません。最大10個の要素に対する特殊ケースのAPI(固定引数オーバーロード)が提供されます。これによりAPIにいくつかの混乱が生じますが、varargs呼び出しで発生する配列の割り当て、初期化、およびガベージコレクションのオーバーヘッドが回避されます。

パフォーマンスの最適化は、varargsメソッドの配列を単純に避けることです。

関連する問題