【发布时间】:2020-12-09 08:41:25
【问题描述】:
我有一个测试程序:
public class App {
public static void main(String[] args) {
List<Integer> a = Arrays.asList(1, 11);
List<Integer> b = Arrays.asList(2, 22);
List<Integer> c = Arrays.asList(3, 33);
Map<String, List<Integer>> map = new HashMap<>();
map.put("a", a);
map.put("b", b);
map.put("c", c);
Set<String> valid = new HashSet<>();
valid.add("a");
Map<Boolean, List<Map.Entry<String, List<Integer>>>> partitions =
map.entrySet().stream()
.collect(Collectors.partitioningBy(
entry -> valid.contains(entry.getKey())));
System.out.println(partitions);
// partition by the key of the map
// then reduce the values into a single collection
Map<Boolean, List<Integer>> result = map.entrySet().stream()
.collect(Collectors.partitioningBy(
entry -> valid.contains(entry.getKey()),
Collectors.mapping(Map.Entry::getValue,
Collectors.reducing(new ArrayList<>(),
(l1, l2) -> {
l1.addAll(l2);
return l1;
}))));
System.out.println(result);
}
}
我期待最终结果是
{false=[b=[2, 22], c=[3, 33]], true=[a=[1, 11]]}
{false=[2, 22, 3, 33], true=[1, 11]}
但在实际结果中,真假键都是6个整数:
{false=[b=[2, 22], c=[3, 33]], true=[a=[1, 11]]}
{false=[1, 11, 2, 22, 3, 33], true=[1, 11, 2, 22, 3, 33]}
请注意,这 2 个分区函数完全相同。但是下游混合了单独分区中的值。这个怎么可能?我假设下游只会在每个分区上运行......
我错过了什么?
谢谢。
【问题讨论】:
-
第一个的等价物是
Map<Boolean, List<Integer>> result = map.entrySet().stream() .collect(Collectors.partitioningBy( entry -> valid.contains(entry.getKey()), Collectors.flatMapping(e -> e.getValue().stream(), Collectors.toList())));。两个分区谓词相同,下游不一样。 -
@Naman,感谢您的评论。您的代码可能有效,但我使用的是没有 flagMapping 的 Java 8。抱歉,我忘了标记 javaj-8。
-
为了减少使用相同的 ArrayList 引用,一个简单的解决方法是
List<Integer> l3 = new ArrayList<>();l3.addAll(l2);l3.addAll(l1);return l3;
标签: java java-8 functional-programming java-stream collectors