2014-05-25 8 views
9

Angenommen, ich habe eine Integer-Liste und ich verwende Java 8 für jede Methode auf der Liste, um ihre Werte zu verdoppeln. Sagen wir, ich habe den folgenden Code:forEach nicht modifizieren java (8) collection

List<Integer> l = Arrays.asList(2,3,6,1,9); 
l.forEach(p->p*=2); 

Als forEach Methode Consumer nehmen und nennt es methos akzeptieren. Ich drucke die Liste nach dem Ausführen des obigen Codes und die ursprüngliche Liste ändert sich nicht.

Soweit ich verstehe Strom nicht die Quelle ändern, aber hier nenne ich nur Methode für jedes Element akzeptieren ...

Thank u in advace

Antwort

13

Der Grund, dass forEach die Liste nicht mutieren kommt auf die Spezifikation:

Die javadoc für forEach sagt:

default void forEach(Consumer<? super T> action)

..... Der Standard Implementierung verhält sich als ob:

 for (T t : this) 
     action.accept(t); 

Wie Sie sehen können:

  • Die action ist ein Consumer; d.h. es erzeugt keinen Wert.
  • Die Semantik erlaubt keine Aktualisierung der this Sammlung.
+0

Vielen Dank für Ihre Antwort. Aber wenn T irgendeine Objektreferenz ist und ich den Inhalt innerhalb von forEach loop ändere, sollte ich seinen neuen Inhalt sehen. – user1409534

+2

Nein, das ist nicht wahr mit oder ohne lambdas und war es nie. –

+0

@ user1409534 - Sie können den Inhalt eines Objekts ändern, auf das die Objektreferenz verweist, aber die Liste wird nicht aktualisiert. Um die Liste zu aktualisieren (in der Art und Weise, wie Sie es versuchen), müssten Sie den Objektverweis in der Liste durch einen anderen ersetzen. Sie können das nicht mit einem 'forEach()' tun. Und sicherlich wird das Lambda es nicht tun/können. –

6

Try map insted forEach zu verwenden, zu verändern Original List.

List<Integer> list = Arrays.asList(2,3,6,1,9); 
list=list.stream().map(p -> p * 2).collect(Collectors.toList()); 
System.out.println(list); 
+8

, dass eine neue Liste erstellt, es doesn Die vorhandene Liste mutieren Sie nicht. Es ist wahrscheinlich besser so, aber es ist immer noch wichtig, sich der Unterscheidung bewusst zu sein. –

+0

Vielen Dank für Ihre Antwort. Ich bin bewusst, die Verwendung von Karte, um neue Sammlung und Karte Metod Stream zu bekommen. Ich verstehe nicht, warum forEach metod on collection das Element nicht ändert, wenn sein einziger Aufruf metode des gegebenen Lambda akzeptiert? – user1409534

18

Verfahren forEach nur iteriert durch die Elemente der Liste, ohne sie zu ändern, wenn Sie die Elemente ändern möchten, können Sie die Methode replaceAll verwenden können:

List<Integer> l = Arrays.asList(2,3,6,1,9); 
l.replaceAll(p->p*2);