Modification d’objects dans un stream Java8 lors d’une itération

Dans les stream Java8, suis-je autorisé à modifier / mettre à jour des objects à l’intérieur? Par exemple List users :

 users.stream().forEach(u -> u.setProperty("value")) 

Oui, vous pouvez modifier l’état des objects à l’intérieur de votre stream, mais vous ne devez pas modifier l’état de la source du stream.

Donc c’est OK

 List users = getUsers(); users.stream().forEach(u -> u.setProperty(value)); 

mais

 users.stream().forEach(u -> users.remove(u)); 

n’est pas et peut lancer une ConcurrentModificationException .

Pour apporter des modifications structurelles à la source du stream, comme Pshemo l’a mentionné dans sa réponse, une solution consiste à créer une nouvelle instance d’une Collection telle que ArrayList avec les éléments de votre liste principale. itère sur la nouvelle liste et effectue les opérations sur la liste principale.

 new ArrayList<>(users).stream().forEach(u -> users.remove(u)); 

La manière fonctionnelle serait à mon sens:

 import static java.util.stream.Collectors.toList; import java.util.Arrays; import java.util.List; import java.util.function.Predicate; public class PredicateTestRun { public static void main(Ssortingng[] args) { List lines = Arrays.asList("a", "b", "c"); System.out.println(lines); // [a, b, c] Predicate predicate = value -> "b".equals(value); lines = lines.stream().filter(predicate.negate()).collect(toList()); System.out.println(lines); // [a, c] } } 

Dans cette solution, la liste d’origine n’est pas modifiée, mais devrait contenir le résultat attendu dans une nouvelle liste accessible sous la même variable que l’ancienne.

Pour se débarrasser de ConcurrentModificationException Use CopyOnWriteArrayList

Au lieu de créer des choses étranges, vous pouvez simplement filter() et ensuite map() votre résultat.

C’est beaucoup plus lisible et sûr. Les stream le feront en une seule boucle.