Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update each element in a List in Java 8 using Stream API

I have a List defined as follows:

List<Integer> list1 = new ArrayList<>();
list1.add(1); 
list1.add(2);

How can I increment each element of the List by one (i.e. end up with a List [2,3]) using Java 8's Stream API without creating new List?

like image 735
Pandey Praveen Avatar asked Nov 29 '22 13:11

Pandey Praveen


2 Answers

When you create a Stream from the List, you are not allowed to modify the source List from the Stream as specified in the “Non-interference” section of the package documentation. Not obeying this constraint can result in a ConcurrentModificationException or, even worse, a corrupted data structure without getting an exception.

The only solution to directly manipulate the list using a Java Stream, is to create a Stream not iterating over the list itself, i.e. a stream iterating over the indices like

IntStream.range(0, list1.size()).forEach(ix -> list1.set(ix, list1.get(ix)+1));

like in Eran’s answer

But it’s not necessary to use a Stream here. The goal can be achieved as simple as

list1.replaceAll(i -> i + 1);

This is a new List method introduced in Java 8, also allowing to smoothly use a lambda expression. Besides that, there are also the probably well-known Iterable.forEach, the nice Collection.removeIf, and the in-place List.sort method, to name other new Collection operations not involving the Stream API. Also, the Map interface got several new methods worth knowing.

See also “New and Enhanced APIs That Take Advantage of Lambda Expressions and Streams in Java SE 8” from the official documentation.

like image 149
Holger Avatar answered Dec 04 '22 10:12

Holger


Holger's answer is just about perfect. However, if you're concerned with integer overflow, then you can use another utility method that was released in Java 8: Math#incrementExact. This will throw an ArithmeticException if the result overflows an int. A method reference can be used for this as well, as seen below:

list1.replaceAll(Math::incrementExact);
like image 23
Jacob G. Avatar answered Dec 04 '22 09:12

Jacob G.