如何使用stream reduce保留所有列表列表

pez*_*tem 7 java-8 java-stream

我遇到了以下问题.我有一个列表列表,我只想保留所有.我正在尝试使用流

private List<List<Long>> ids = new ArrayList<List<Long>>();

// some ids.add(otherLists);  

List<Long> reduce = ids.stream().reduce(ids.get(0), (a, b) -> a.addAll(b));
Run Code Online (Sandbox Code Playgroud)

不幸的是我收到了错误

Error:(72, 67) java: incompatible types: bad return type in lambda expression
    boolean cannot be converted to java.util.List<java.lang.Long> 
Run Code Online (Sandbox Code Playgroud)

Ale*_* C. 22

如果你想减少(我认为你的意思是扁平化)列表列表,你应该这样做:

import static java.util.stream.Collectors.toList

...

List<Long> reduce = ids.stream().flatMap(List::stream).collect(toList());
Run Code Online (Sandbox Code Playgroud)

使用时reduce,第一个值应该是您的实现中不是这种情况的标识值,并且您的解决方案将在并行运行流时产生意外结果(因为addAll修改了列表,在这种情况下,标识值将是部分结果的相同列表).

您需要复制部分结果列表的内容,并在其中添加其他列表,以便在管道并行运行时使其工作:

List<Long> reduce = ids.parallelStream().reduce(new ArrayList<>(), (a, b) -> {
    List<Long> list = new ArrayList<Long>(a);
    list.addAll(b);
    return list;
 });
Run Code Online (Sandbox Code Playgroud)

  • 另外一个用于强调关于"减少"的观点需要适当的身份价值. (4认同)
  • 或者`collect(ArrayList :: new,List :: addAll,List :: addAll)`,它是专为使用可变容器而设计的.但是,"flatMap"方法要简单得多. (3认同)

lba*_*scs 5

addAll 返回一个布尔值,而不是两个列表的并集。你要

List<Long> reduce = ids.stream().reduce(ids.get(0), (a, b) -> {
    a.addAll(b);
    return a;
});
Run Code Online (Sandbox Code Playgroud)