Java sammeln mit lambda-expression-Beispiel
War ich versucht zu konvertieren, das
String r = "";
for ( Persona p : list ) {
r += p.lastName;
}
Zu stream().filter.collect()
form, aber ich möchte wissen, wie man die collect
mit ein lambda-Ausdruck (nicht-Methode Referenzen). Ich konnte Sie nicht finden, ein gutes Beispiel.
Dies ist, was ich haben
class B {
public static void main( String ... args ) {
List<Person> p = Arrays.asList(
new Person("John", "Wilson"),
new Person("Scott", "Anderson"),
new Person("Bruce", "Kent"));
String r;
String s = p.stream()
.filter( p -> p.lastName.equals("kent"))
.collect((r, p) -> r += p.lastName);///?????
}
}
class Person {
String name;
String lastName;
public Person( String name, String lastName ) {
this.name = name;
this.lastName = lastName;
}
}
Allen Beispielen, die ich finde sind mit der Methode Verweise, während ich denke es sollte eine einfache Möglichkeit zum schreiben eines lambda-Ausdrucks statt.
- Haben Sie sah
Collectors.joining()
oder ist die Frage nach der Umsetzung es selbst? - stackoverflow.com/questions/31456898/...
- Die Frage ist, wie die Verwendung eines lambda-Ausdrucks, so etwas wie:
.collect( (acc, p ) -> acc += p.lastName);
- Das ist nicht wirklich, wie es funktioniert. Müssen Sie zunächst die Zuordnung jeder person zu deren Nachname mit
map(person -> person.lastName)
und dann können Sie sammeln, werden diese Zeichenfolgen mit.collect(joining())
. - Die Lektion, die Sie lernen sollen, ist, dass Sie 99% der Zeit sollten mit einem pre-build Sammler, und alle den rest der Zeit sollten Sie mit
Collector.of
oder mitcollect(Supplier, BiConsumer, BiConsumer)
. - Gut, die Frage ist, genau zu erfahren, dass die 1%. Ich weiß, wie man es mit der Methode Verweise, aber ich habe Mühe mit lambdas Ausdrücken. Die Tatsache, dass ich mehr Kommentare als Antworten gibt an, dass dies schwer für alle anderen auch.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Vorausgesetzt, Sie wollen nicht zu verwenden ready-made-Sammler wie
Collectors.joining()
könnten Sie in der Tat erstellen Sie Ihre eigenen Sammler.Aber, wie in der javadoc-zeigt an, sammeln() erwartet, dass entweder 3 funktionale interface Instanzen als argument oder ein Sammler. So kann man nicht einfach einen einzigen lambda-Ausdruck, um zu sammeln().
Vorausgesetzt, Sie verwenden möchten die erste version, unter 3 lambda-Ausdrücke, werden Sie bemerken, durch das Lesen der javadoc, dass das Ergebnis muss ein mutable object und String sind nicht veränderlich. Also sollten Sie stattdessen einen StringBuilder. Zum Beispiel:
Nutzt diese Methode Referenzen, aber alle Methoden-Referenzen kann geschrieben werden als lambda-Ausdrücke. Die oben ist äquivalent zu
reduce
statt?Collectors.joining()
entsprichtCollector.of(StringBuilder::new, StringBuilder::append, StringBuilder::append, StringBuilder::toString)
, die sich nur mit dem finisher-Funktion, die wiederum dieStringBuilder
in eineString
.Können Sie auch die
.reduce()
Funktion, es ist einfacher zu Lesen als das sammeln.Version mit
StringBuilder
:reduce
erfordert eineBinaryOperator<T>
, aber es gibt keine+
Betreiber geltendenPersona
.Collectors.joining()
. Aber die Frage war etwa, wie Sie schreiben Ihre eigenen sammeln mithilfe von lambda-Ausdrücken.BinaryOperator
. Zum Beispiel String s = Personen.stream() .Karte( p -> p.lastName ) .die Verringerung der((r, ln) -> r + ln) .orElse("");reduce
mit einemStringbuilder
wie Sie es tun. Diese ist gebrochen. Sie müssen verstehen, den Unterschied zwischen Reduction und Veränderlich Reduktion.Vielleicht waren Sie Vorstellungsvermögen eine
reduce
Betrieb eher als ein sammeln, die Ihnen erlauben würde, die Verwendung eines lambda-Ausdrucks, wie Sie sich das vorgestellt haben. Zum Beispiel,Dies ist eine übung, natürlich. Die String-Verkettung ist ineffizient, so wäre es am besten zu verwenden
collect(Collectors.joining())
verwendetStringBuffer
wie sein Akku.StringBuil..Buffer
wenn Sie es schaffen, auf jeder iteration?Könnten Sie weglassen, das mapping mit dieser Lösung: