私は「それが指定されていない」ことにする答えを疑うが...Stream.max()はどのように等価を扱いますか?
maxまたはminメソッドに渡されたComparator
が等しい(リターン0
)とみなしStream
内に複数の「最大/最小の」要素がある場合どの要素が見つかるのかはどこかで指定されていますか?
私は「それが指定されていない」ことにする答えを疑うが...Stream.max()はどのように等価を扱いますか?
maxまたはminメソッドに渡されたComparator
が等しい(リターン0
)とみなしStream
内に複数の「最大/最小の」要素がある場合どの要素が見つかるのかはどこかで指定されていますか?
確かに、ドキュメントから明確なステートメントを引き出すのは難しいです。 "Reduction"プロセスの一般的な記述やドキュメンテーションの同様のヒントから結論を導き出そうとすると、あまりにも多くの解釈をしているような気がします。
しかし、ストリームAPIについてはかなり権威だBrian Goetzからexplicit statement regarding this matterがあります:ストリームが(例えば、あなたが配列やリストから取得するストリームとして)注文された場合
、それは最初を返します。複数の最大要素がある場合に最大の要素。ストリームが順序付けられていない場合にのみ、任意の要素を選択することが許されます。
このような明示的な文が右Stream.max
の文書で行われていないことは残念だが、少なくとも、それが実装(those of us who looked at the source code)の経験と知識に沿ってあります。 max
が最初の任意の要素を選ぶことが許可されていた場合は、「最初より優先して選択する」と言うのは簡単で、忘れてはならないのは、unordered().max(comparator)
を介して現在の状態で " 。
ソースコードを読んだ後、私はコレクションの順序に従って見つけられる最初の最大の要素であるべきだと思います。 我々は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;
}
それは明らかだ、a
はb
に等しいとき、それはを返すの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);
動作が定義されていないようです。 –
私はそれが基本的なコレクションに依存すると思います。 – munyengm
サイド質問:なぜ重要なのですか? – Tunaki