Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modifying Objects within stream in Java8 while iterating

In Java8 streams, am I allowed to modify/update objects within? For eg. List<User> users:

users.stream().forEach(u -> u.setProperty("value")) 
like image 590
Tejas Gokhale Avatar asked Jun 11 '15 10:06

Tejas Gokhale


People also ask

Does Java stream modify elements?

Java stream mappingIt is possible to change elements into a new stream; the original source is not modified. The map method returns a stream consisting of the results of applying the given function to the elements of a stream.

Can we modify a list while iterating Java?

The Best Answer is It's not a good idea to use an enhanced for loop in this case, you're not using the iteration variable for anything, and besides you can't modify the list's contents using the iteration variable.

Can we update list while iterating?

Yes, that is a very important point, and all programmers should think about this very carefully. As a general rule in programming, you should avoid mutating an object while iterating over it, unless it is the specific purpose of the function to mutate the original object.

What would you use while processing a stream to replace every element in a stream with a different value?

In a nutshell, flatMap lets you replace each value of a stream with another stream, and then it concatenates all the generated streams into one single stream. Note that flatMap is a common pattern.


1 Answers

Yes, you can modify state of objects inside your stream, but most often you should avoid modifying state of source of stream. From non-interference section of stream package documentation we can read that:

For most data sources, preventing interference means ensuring that the data source is not modified at all during the execution of the stream pipeline. The notable exception to this are streams whose sources are concurrent collections, which are specifically designed to handle concurrent modification. Concurrent stream sources are those whose Spliterator reports the CONCURRENT characteristic.

So this is OK

  List<User> users = getUsers();   users.stream().forEach(u -> u.setProperty(value)); //                       ^    ^^^^^^^^^^^^^ //                        \__/ 

but this in most cases is not

  users.stream().forEach(u -> users.remove(u)); //^^^^^                       ^^^^^^^^^^^^ //     \_____________________/ 

and may throw ConcurrentModificationException or even other unexpected exceptions like NPE:

List<Integer> list = IntStream.range(0, 10).boxed().collect(Collectors.toList());  list.stream()     .filter(i -> i > 5)     .forEach(i -> list.remove(i));  //throws NullPointerException 
like image 132
Pshemo Avatar answered Sep 16 '22 11:09

Pshemo