2017-03-12 4 views
1

ich einen Ausschnitt schreibe:Wie funktioniert foreach() Methode funktioniert in Java 8

List<Integer> list=Arrays.toList(2,4,6,8); 
list.forEach(i -> System.out.println(i)); 

Bitte erläutern Sie mir den Fluss des Methodenaufrufes in dem obigen Code-Schnipsel. Wie übergibt die forEach() -Methode die Parameter an die accept() -Methode? Ruft die forEach() -Methode jedes Mal die Methode accept auf? Bitte korrigieren Sie mich, wenn ich falsch liege.

i-> System.out.println(i) 

gibt ein Objekt der Consumer-Schnittstelle zurück. forEach() ruft die Methode accept() dieses Objekts mit i als Parameter auf.

+0

Was ist diese 'accept()' Methode, von der Sie sprechen? – azurefrog

+2

Es ist die einzige abstrakte Methode der funktionalen Schnittstelle "Consumer". – Deb

+0

@azurefrog: [Dieser] (http://docs.oracle.com/javase/8/docs/api/java/util/function/Consumer.html#accept-T-). –

Antwort

7

Da Consumer ein functional interface ist, kann Ihre Lambda-Funktion dies implizit erfüllen. Also, wenn Sie tun

list.forEach(i -> System.out.println(i)); 

, was Sie tun konzeptionell (mehr unten) ist

list.forEach(new Consumer<String>() { 
    @Override 
    public void accept(String i) { 
     System.out.println(i); 
    } 
}); 

Die Instanz dann in forEach übergeben wird, die für jeden Eintrag in der Liste seiner accept Methode aufruft .

Aus einem Kommentar, den Sie über die Frage gestellt:

Ich bin verwirrt, die Methode zuerst aufgerufen wird. Ist es das "forEach()" oder das "accept()", weil beide zusammen arbeiten!

die Ordnung der Dinge ist:

  • Eine Instanz der anonymen Klasse erstellt (in der Tat über den invokedynamic Betrieb)
  • forEach genannt wird, in dieser Literaturstelle vorbei
  • forEach 's code ruftaccept wiederholt auf, wobei jedes Mal eines der Listenelemente hineingelangt (welches es empfängt) s i)

Hinweis, sagte ich konzeptionell. Eine anonyme Klasse wird nicht wirklich vom Compiler erstellt; Stattdessen wird eine neue Bytecode-Operation namens invokedynamic zum Erstellen der Consumer-Instanz verwendet.

+0

Die 'list.forEach (i -> System.out.println (i)); 'kann auch unter Verwendung der Methodenreferenz als' list.forEach (System.out :: println); 'geschrieben werden. Auch der gesamte Code kann einfach sein: 'Arrays.asList (2, 4, 6, 8) .forEach (System.out :: println); ' –