我应该在Java 8 Streams中使用共享的可变变量更新吗

Thi*_*asu 7 java java-8 java-stream

只需在列表下面进行迭代并通过Java 8流添加到另一个共享的可变列表中。

List<String> list1 = Arrays.asList("A1","A2","A3","A4","A5","A6","A7","A8","B1","B2","B3");
List<String> list2 = new ArrayList<>();

Consumer<String> c = t -> list2.add(t.startsWith("A") ? t : "EMPTY");

list1.stream().forEach(c);
list1.parallelStream().forEach(c);
list1.forEach(c);
Run Code Online (Sandbox Code Playgroud)

以上三个迭代与我们需要使用哪个迭代有什么区别。有什么考虑吗?

Moh*_*and 3

从功能上来说,对于简单的情况来说它们几乎是相同的,但总的来说,存在一些隐藏的差异:

\n\n
    \n
  1. 让我们首先引用forEachfor iterable use-cases 的 Javadoc 指出:
  2. \n
\n\n
\n

对 Iterable 的每个元素执行给定的操作,直到处理完所有\n 元素或该操作引发异常。

\n
\n\n

我们还可以迭代集合并对每个元素 \xe2\x80\x93 执行给定的操作,只需传递一个实现 Consumer 接口的类

\n\n
void forEach(Consumer<? super T> action)\n
Run Code Online (Sandbox Code Playgroud)\n\n

https://docs.oracle.com/javase/8/docs/api/java/lang/Iterable.html#forEach-java.util.function.Consumer-

\n\n
\n\n
    \n
  1. 的顺序Stream.forEach是随机的,而Iterable.forEach始终按照 的迭代顺序执行Iterable
  2. \n
\n\n
\n\n
    \n
  1. 如果Iterable.forEach迭代同步集合Iterable.forEach获取集合的锁一次,并在对操作方法的所有调用中保持它。Stream.forEach 调用使用集合的 spliterator,它不会锁定
  2. \n
\n\n
\n\n
    \n
  1. 中指定的操作Stream.forEach要求是互不干扰的,同时Iterable.forEach允许在底层中设置值ArrayList而不出现问题。
  2. \n
\n\n
\n\n
    \n
  1. 在Java 中,Collection 类(例如ArrayList、HashSet、Vector 等)返回的迭代器会快速失败。这意味着,如果您在迭代时尝试从底层数据结构中添加()或删除(),您会得到一个ConcurrentModificationException.
  2. \n
\n\n

https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#fail-fast

\n\n
\n\n

更多信息:

\n\n
\n \n
\n