简体   繁体   English

如何使用Stream API更新Java 8中List中的每个元素

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

I have a List defined as follows: 我有一个List定义如下:

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? 如何在不创建新列表的情况下使用Java 8的Stream API将List的每个元素递增一个(即最终使用List [2,3] )?

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 . List创建Stream ,不允许按照程序包文档“无干扰”部分中的说明Stream修改源List Not obeying this constraint can result in a ConcurrentModificationException or, even worse, a corrupted data structure without getting an exception. 不遵守此约束可能会导致ConcurrentModificationException或者更糟糕的是,导致数据结构损坏而不会出现异常。

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 使用Java Stream直接操作列表的唯一解决方案是创建一个不迭代列表本身的Stream,即迭代索引之类的流

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. 但是这里没有必要使用Stream 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. 这是Java 8中引入的一种新的List方法 ,也允许平滑地使用lambda表达式。 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. 除此之外,还有一个众所周知的Iterable.forEach ,很好的Collection.removeIf和就地List.sort方法,用于命名其他不涉及Stream API的新Collection操作。 Also, the Map interface got several new methods worth knowing. 此外, Map接口有几个值得了解的新方法。

See also “ New and Enhanced APIs That Take Advantage of Lambda Expressions and Streams in Java SE 8 ” from the official documentation. 另请参阅官方文档中的“ 在Java SE 8中利用Lambda表达式和流的新增和增强的API ”。

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 . 但是,如果您关注整数溢出,那么您可以使用Java 8中发布的另一个实用程序方法: Math#incrementExact This will throw an ArithmeticException if the result overflows an int . 如果结果溢出int则会抛出ArithmeticException 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 : 您可以通过结合forEachIntStream迭代索引:

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. 然而,这与正常的for循环没有太大的不同,并且可能不太可读。

将结果重新分配给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;

    };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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