2017-02-16 5 views
-1

Von den folgenden Zeilen, warum ist die erste und letzte erlaubt?Wann soll ich Doppelpunkt Doppelpunkt mit Lambda verwenden?

List<String> l = new ArrayList<>(); 

l.stream().forEach(System.out::println);//compiles 
l.stream().forEach(System.out.println(String::compareTo));//doesnt compile 
l.stream().forEach(String::compareTo);// doesnt compile 

String comparedWith = ""; 

l.stream().forEach(comparedWith::compareTo);//compiles why ? 

bearbeiten

Wenn compareToein Argument nimmt, sollte es nicht auch funktionieren?

Wenn docs gemäß:

eine Operation darstellt, die kein Ergebnis ein einziges Eingabeargument und kehren annimmt. Im Gegensatz zu den meisten anderen funktionalen Schnittstellen wird erwartet, dass {@code Consumer} über Nebeneffekte funktioniert.

Antwort

2

l.stream() foreach (System.out :: println); // kompiliert

Dies ruft die println Methode der System.out für jedes Element. Hier System.out::println ist das gleiche wie (String x) -> System.out.println(x).

l.stream() foreach (System.out.println (String :: compareTo));. // doesnt kompilieren

Sie wissen, wie Funktion Arbeit nennt, nicht wahr? Dieser ruft zuerst (System.out.println(String::compareTo), dann ruft l.stream().forEach(result of that println call). Außer println gibt void zurück, also hat es kein Ergebnis. .

l.stream() foreach (String :: compareTo); // doesnt

Hier String::compareTo kompilieren ist die gleiche wie (String x, String y) -> x.compareTo(y), die zwei Argumente übernimmt. Aber forEach benötigt ein Lambda, das ein Argument benötigt.

String comparedWith = "";

l.stream(). ForEach (comparedWith :: compareTo); // kompiliert warum?

Hier comparedWith::compareTo ist das gleiche wie (String x) -> comparedWith.compareTo(x). Dies benötigt ein Argument, damit es gültig ist.

+0

Warum ist das dritte Beispiel dasselbe wie '(String x, String y) -> x.compareTo (y)', können Sie das bitte ausführen? –

+1

@estebanrincon, weil 'String's Methode' compareTo' nicht statisch ist und daher einen String benötigt, der aufgerufen werden soll; Es nimmt auch einen anderen String als Argument. – immibis

+0

Ah, verstanden, danke! –

1

forEach wird jedes Element der Sammlung übernehmen und an Ihre Funktion übergeben. Ihre Funktion muss also nur ein Argument haben.

In Ihrem Fall, println nimmt ein Argument, also passt es in die Operation forEach akzeptiert. Wenn Sie die Instanz der Zeichenfolge (comparedWith) und compareTo aufrufen, wird ein Argument benötigt und die aktuelle Zeichenfolge (leere Zeichenfolge in Ihrem Fall) mit Ihrem Argument verglichen. Es gibt keine statischen Methoden in String, die compareTo heißen, also funktioniert String :: compareTo nicht. .

+0

'compareTo' nimmt auch ein Argument, also warum funktioniert es nicht? –

+0

'comapareTo' nimmt tatsächlich zwei Argumente, den 'this' Verweis auf die aufrufende Instanz, und den deklarierten Parameter:' x.compareTo (y) '. Wie oben erwähnt, ist das entsprechende Lambda "(x, y) -> x.compareTo (y)". Der Stream 'forEach' kann nur eines von' x' oder 'y' herausfinden, so dass es nicht kompiliert wird. –

1

Der doppelte Doppelpunkt oder genauer "Methodenreferenz" bezeichnet eine Methode, die aufgerufen wird.

Und wenn Methoden aufgerufen werden, ist es wichtig, die Anzahl der bereitgestellten und erwarteten Argumente zu vergleichen.

Und wie Sie leicht abziehen können, stimmen diese Zahlen für Ihr zweites Beispiel nicht überein.

Verwandte Themen