2016-04-19 12 views
9

私は「それが指定されていない」ことにする答えを疑うが...Stream.max()はどのように等価を扱いますか?

maxまたはminメソッドに渡されたComparatorが等しい(リターン0)とみなしStream内に複数の「最大/最小の」要素がある場合どの要素が見つかるのかはどこかで指定されていますか?

+5

動作が定義されていないようです。 –

+3

私はそれが基本的なコレクションに依存すると思います。 – munyengm

+2

サイド質問:なぜ重要なのですか? – Tunaki

答えて

3

確かに、ドキュメントから明確なステートメントを引き出すのは難しいです。 "Reduction"プロセスの一般的な記述やドキュメンテーションの同様のヒントから結論を導き出そうとすると、あまりにも多くの解釈をしているような気がします。

しかし、ストリームAPIについてはかなり権威だBrian Goetzからexplicit statement regarding this matterがあります:ストリームが(例えば、あなたが配列やリストから取得するストリームとして)注文された場合

、それは最初を返します。複数の最大要素がある場合に最大の要素。ストリームが順序付けられていない場合にのみ、任意の要素を選択することが許されます。

このような明示的な文が右Stream.maxの文書で行われていないことは残念だが、少なくとも、それが実装(those of us who looked at the source code)の経験と知識に沿ってあります。 maxが最初の任意の要素を選ぶことが許可されていた場合は、「最初より優先して選択する」と言うのは簡単で、忘れてはならないのは、unordered().max(comparator)を介して現在の状態で " 。

+2

JDK開発者が管理していないサードパーティの 'Stream'実装があるため、明示的な記述があまり価値がないと思います。また、javadocがこれらの実装を制約していない場合でも、このケースを自由に処理できます。 – the8472

+2

@ the8472:本当に?少なくとも1つの名前を指定してください... – Holger

+2

@ the8472:この文は空白になっていません。すでに答えたように、文書のいくつかの側面は、そのような結論を導き出すことを可能にします。その明示的な声明は、私たちがここで過度に解釈していないことを証明しているに過ぎません。 – Holger

4

ソースコードを読んだ後、私はコレクションの順序に従って見つけられる最初の最大の要素であるべきだと思います。 我々はStream.max(Comparator<? super T> comparator)のソースコードをチェックアウトすることができ、実装クラスを使用すると、Stream.maxを呼び出すとき、あなたはStream.reduce(BinaryOperator<P_OUT> accumulator)

を呼び出し、ソースコードを見て意味、あなたが見ることができるReferencePipeline.max

@Override 
    public final Optional<P_OUT> max(Comparator<? super P_OUT> comparator) { 
     return reduce(BinaryOperator.maxBy(comparator)); 
    } 

ですBinaryOperator.maxBy(comparator)

public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) { 
     Objects.requireNonNull(comparator); 
     return (a, b) -> comparator.compare(a, b) >= 0 ? a : b; 
    } 

それは明らかだ、abに等しいとき、それはを返すの0。したがって、ストリーム内に複数の「最大/最小」要素がある場合、「最大/最小」要素は、収集順序に従って最初の「最大/最小」要素にする必要があります。

例があります。あなたの参照。

 List<Student> list = Arrays.asList(new Student("s1", 1), new Student("s2", 5), new Student("s3", 3), new Student("s4", 5)); 
     // it should be student of 's2' 
     list.stream().max(Comparator.comparing(Student::getScore)); 
     // it should be student of 's4' 
     list.stream().reduce((a, b) -> Comparator.comparing(Student::getScore).compare(a, b) > 0 ? a : b); 
+2

これは本当にストリームの順序に依存します。もっと詳しくはこちらhttp://stackoverflow.com/a/29218074/1743880 – Tunaki

+1

@ Tunaki:Thanks Tunaki、私はたくさんのことを学びます。 :) – Tony

+4

ソースは有益ですが、標準ではありません。ドキュメンテーションの一部でない限り、物事に頼ることはできません。 – the8472