我正在使用Java 8流,并尝试在forEach终端操作中修改对象内容。
我在这里面临的问题是我能够修改List<Employee>
对象的内容,但不能修改List<Integer>
的内容
代码段如下:
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);
}
我想知道,由于执行a=a+1
操作时取消对Integer对象的装箱操作,但不确定该更改是否不会反映在列表中。
答案 0 :(得分:3)
您正在将新值分配给局部变量(a
),因此这对第二个Stream
(您的List<Integer>
)的源没有影响。请注意,这与您在List<Employee>
上执行的操作不同,在这里您要调用setter方法来对List
的元素进行变异。
由于Integer
是不可变的,因此您无法更改输入List<Integer>
的元素。
相反,您可以创建一个新的List
:
List<Integer> newList =
listInteger.stream()
.map(v -> v % 2 == 0 ? v + 1 : v)
.collect(Collectors.toList());
或者您可以流式传输List
的索引,并替换该List
的某些元素:
IntStream.range(0,listInteger.size())
.filter(i -> listInteger.get(i) % 2 == 0)
.forEach(i -> listInteger.set(i, listInteger.get(i + 1));
答案 1 :(得分:3)
您使用的不是Stream
的最佳方法。请考虑一下Stream
中的每个步骤,因为修改存在(或创建新的)元素,并将其返回到Stream
。最终,您收到final
的结果,并且可以使用final
方法之一来完成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);
这里有初始数组。您要执行以下操作:
final
步骤); final
步骤)。为此,您不必两次创建Streams
。使用一个:
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
注意::Stream.of(...)
创建一个Stream
,然后向流filter
和map
添加两个步骤,然后向{{1} }或 START 使用finalize
创建的流。