Reputation: 916
I am working with java 8 stream and trying to modify the object content in the forEach terminal operation.
The issues which i am facing here is that i am able to modify the List<Employee>
object contents but not able to modify the contents of List<Integer>
The code snippet is as follows:
public static void streamExample() {
List<Employee> listEmp = Arrays.asList(new Employee());
listEmp.stream().forEach(a -> a.setEmptName("John Doe"));
listEmp.stream().forEach(System.out::println);
List<Integer> listInteger = Arrays.asList(2, 4, 6, 8, 12,17, 1234);
listInteger.stream().filter(v -> v % 2 == 0).forEach(a -> a=a+1);
listInteger.stream().forEach(System.out::println);
}
I am wondering the change is not reflecting back in the list because of unboxing the Integer object while performing the a=a+1
operation but not sure.
Upvotes: 3
Views: 1311
Reputation: 18245
You use not optimal approach of Stream
. Do think of each step in Stream
as modify existed (or create new) element and return it back to the Stream
. Finally you receive final
result and you can use one of final
method to finalize (and actually run the whole stream working) the Stream
:
List<Integer> listInteger = Arrays.asList(2, 4, 6, 8, 12, 17, 1234);
listInteger.stream().filter(v -> v % 2 == 0).forEach(a -> a = a + 1);
listInteger.stream().forEach(System.out::println);
Here you have initial array. You want to do following:
final
step);final
step).To do so, you do not have to create Streams
two times. Do use one:
Stream.of(2, 4, 6, 8, 12, 17, 1234) // create stream (there're many way to do it)
.filter(v -> v % 2 == 0) // filter out required elements
.map(v -> v + 1) // transform elements using given rule
.forEach(System.out::println); // finalize stream with printing out each element separately
Note: Stream.of(...)
creates a Stream
, then we add two steps to the stream filter
and map
and then finalize
or START created stream with forEach
.
Upvotes: 3
Reputation: 393781
You are assigning a new value to a local variable (a
), so that has no affect on the source of the second Stream
(your List<Integer>
). Note that this is not what you are doing with your List<Employee>
, where you are calling a setter method to mutate the elements of the List
.
Since Integer
s are immutable, you can't mutate the elements of your input List<Integer>
.
Instead, you can create a new List
:
List<Integer> newList =
listInteger.stream()
.map(v -> v % 2 == 0 ? v + 1 : v)
.collect(Collectors.toList());
Or you can stream over the indices of your List
, and replace some of the elements of that List
:
IntStream.range(0,listInteger.size())
.filter(i -> listInteger.get(i) % 2 == 0)
.forEach(i -> listInteger.set(i, listInteger.get(i + 1));
Upvotes: 3