wake-up-neo.com

Max mit Lambda Expression in Java finden

Das ist mein Code

    List<Integer> ints = Stream.of(1,2,4,3,5).collect(Collectors.toList());
    Integer maxInt = ints.stream()
                              .max(Comparator.comparing(i -> i))
                              .get();

    System.out.println("Maximum number in the set is " + maxInt);

ausgabe:

Maximum number in the set is 5

Ich kann keine Unterscheidung zwischen zwei i im unteren Abschnitt meines Codes machen

Comparator.comparing(i -> i)

kann jemand nett sein und den Unterschied zwischen zwei i erklären?

13
Kick Buttowski

Die Methode Comparator.comparing(…) soll ein Comparator erstellen, das eine Reihenfolge verwendet, die auf einer zu vergleichenden Eigenschaft der Objekte basiert. Wenn Sie den Lambda-Ausdruck i -> i verwenden. Hierbei handelt es sich um eine kurze Schreibweise für (int i) -> { return i; } hier als Eigenschafts-Provider-Funktion. Der resultierende Comparator vergleicht die Werte selbst. Dies funktioniert, wenn die zu vergleichenden Objekte eine natürliche Ordnung haben wie Integer.

So

Stream.of(1,2,4,3,5).max(Comparator.comparing(i -> i))
.ifPresent(maxInt->System.out.println("Maximum number in the set is " + maxInt));

macht das gleiche wie

Stream.of(1,2,4,3,5).max(Comparator.naturalOrder())
.ifPresent(maxInt->System.out.println("Maximum number in the set is " + maxInt));

letzteres ist jedoch effizienter, da es als Singleton für alle Typen implementiert wird, die eine natürliche Reihenfolge haben (und Comparable implementieren).

Der Grund, warum max überhaupt ein Comparator erfordert, liegt darin, dass Sie die generische Klasse Stream verwenden, die beliebige Objekte enthalten kann.

Dies ermöglicht z. Verwenden Sie es wie streamOfPoints.max(Comparator.comparing(p->p.x)), um den Punkt mit dem größten x-Wert zu finden, während Point selbst keine natürliche Reihenfolge hat. Oder machen Sie etwas wie streamOfPersons.sorted(Comparator.comparing(Person::getAge)).

Wenn Sie die spezialisierte IntStream verwenden, können Sie die natürliche Reihenfolge direkt verwenden, die wahrscheinlich effizienter ist:

IntStream.of(1,2,4,3,5).max()
.ifPresent(maxInt->System.out.println("Maximum number in the set is " + maxInt));

Um den Unterschied zwischen "natürlicher Ordnung" und einer objektbasierten Reihenfolge zu veranschaulichen:

Stream.of("a","bb","aaa","z","b").max(Comparator.naturalOrder())
.ifPresent(max->System.out.println("Maximum string in the set is " + max));

dies wird gedruckt

Die maximale Zeichenfolge in der Gruppe ist z

als natürliche Reihenfolge von Strings ist die lexikographische Reihenfolge, in der z größer als b ist, die größer als a ist.

Auf der anderen Seite

Stream.of("a","bb","aaa","z","b").max(Comparator.comparing(s->s.length()))
.ifPresent(max->System.out.println("Maximum string in the set is " + max));

wird drucken

Die maximale Zeichenfolge im Set ist aaa

as aaa hat die maximale length aller Strings im Stream. Dies ist der beabsichtigte Anwendungsfall für Comparator.comparing, der durch die Verwendung von Methodenreferenzen noch lesbarer gemacht werden kann, d. H. Comparator.comparing(String::length), was fast für sich selbst spricht…

20
Holger

Diese Funktion (Anmerkung -> ist für Schließungen und nicht mit => zu verwechseln, die zum Vergleich dient)

i -> i

sie müssen lediglich das gesamte Objekt so vergleichen, wie es ist. Wenn ich eine i habe, müssen Sie i vergleichen.

Ein weniger triviales Beispiel könnte sein

max(Comparator.comparing(i -> -i))

das gibt Ihnen das Minimum oder

max(Comparator.comparing(i -> Math.abs(100-i))

gibt Ihnen einen Wert, der am weitesten von 100 entfernt ist.

max(Comparator.comparing(i -> i.toString()))

dies gibt Ihnen den maximalen Vergleich als String, d. h. "9"> "10" als String.

3
Peter Lawrey

Comparator.comparing erwartet eine Funktion, die das Quellobjekt auf den Wert abbildet, der tatsächlich verglichen wird. Da Sie den zu vergleichenden Wert nicht vorverarbeiten möchten, wird i einfach auf sich selbst abgebildet.

0
Smutje