我们可以从 Java 8 流中收集两个列表吗?

问题描述 投票:0回答:5

假设我有一个包含两种类型数据的列表,一种有效,另一种无效。

如果我开始过滤此列表,我可以在最后收集两个列表吗?

java java-8 java-stream
5个回答
9
投票

我们可以从 Java 8 流中收集两个列表吗?

你不能,但如果你有办法根据条件对

List
的元素进行分组。 在这种情况下,您可以使用
Collectors.groupingBy()
来返回
Map<Foo, List<Bar>>
,其中
Map
的值是两个列表。

请注意,在您的情况下,您不需要流来仅进行过滤。

使用

removeIf()
过滤无效列表并将其所有元素添加到第一个列表中:

invalidList.removeIf(o -> conditionToRemove);
goodList.addAll(invalidList);      

如果您不想更改

goodList
的状态,您可以对其进行浅复制:

invalidList.removeIf(o -> conditionToRemove);
List<Foo> terminalList = new ArrayList<>(goodList);
terminalList.addAll(invalidList);

5
投票

使用 Java 8 流 API 的一种方法是使用

Collectors.partitioningBy
收集器。假设我有
List
String
元素:输入列表包含不同长度的字符串;只有长度为 3 的字符串才有效。

List<String> input = Arrays.asList("one", "two", "three", "four", "five");
Map<Boolean, List<String>> map =
        input.collect(Collectors.partitioningBy(s -> s.length() == 3));
System.out.println(map); // {false=[three, four, five], true=[one, two]}

List<String> valid = map.get(true);    // [one, two]
List<String> invalid = map.get(false); // [three, four, five]

生成的

Map
只有两条记录;一个包含有效的输入列表元素,另一个包含无效的输入列表元素。带有 key=true
 的地图记录具有 
List
 形式的有效字符串:一、二。另一个是 
key=false
 和无效字符串:三、四、五。

请注意,

Collectors.partitioningBy

 始终在结果映射中生成两条记录,无论是否存在有效值或无效值。


2
投票
另一个建议:使用

lambda

 进行过滤,将要从流中过滤的元素添加到单独的列表中。 


2
投票
收集器只能返回单个对象!

但是您可以创建一个自定义收集器,只需将流元素放入两个列表中,然后返回包含这两个列表的列表列表。

有很多

示例如何做到这一点。


1
投票
如果您需要对二进制进行分类(true | false),您可以使用

Collectors.partitioningBy 它将返回 Map(或其他下游集合,如 Set,如果您另外指定)。

如果您需要 2 个以上类别 - 使用

groupBy 或仅使用集合的 Collectors.toMap

© www.soinside.com 2019 - 2024. All rights reserved.