简体   繁体   中英

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 (ie end up with a List [2,3] ) using Java 8's Stream API without creating new List?

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, ie 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.

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);

You can iterate over the indices via an IntStream combined with forEach :

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

However, this is not much different than a normal for loop, and probably less readable.

将结果重新分配给list1

list1 = list1.stream().map(i -> i+1).collect(Collectors.toList());
public static Function<Map<String, LinkedList<Long>>, Map<String, LinkedList<Long>>> applyDiscount = (

            objectOfMAp) -> {


        objectOfMAp.values().forEach(listfLong -> {


            LongStream.range(0, ((LinkedList<Long>) listfLong).size()).forEach(index -> {

                Integer position = (int) index;

                Double l = listfLong.get(position) - (10.0 / 100 * listfLong.get(position));

                listfLong.set(position, l.longValue());

            });

        });

        return objectOfMAp;

    };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM