如何从成对的流中创建集合映射



我对创建包含集合的映射的特定Java流有问题。我发现是一种的方式,但我觉得有一种更好(更具表演性和可读性(的方式来表达这一点。

如果有任何改进的想法,我们将不胜感激!

想法

输入:

[["A", 1], ["A", 2], ["B", 3], ["D", 1], ["D", 5]]

输出:

["A"={1, 2}, "B"={3}, "D"={1, 5}]

实施

public static <L, R> Map<L, Set<R>> pairsToMap(Stream<Pair<L, R>> pairs) {
return pairs.collect(
Collectors.toMap(Pair::getLeft,
// FIXME: Creating a new HashSet for each Pair... :/
p -> new HashSet<>(Collections.singleton(p.getRight())),
// merge existing set with new set
(a, b) -> {
a.addAll(b);
return a;
}
)
);
}

注意:配对是我自己的实现,基本上如下:

public class Pair<L, R> {
/* ... */

public L getLeft() { /*...*/ }
public R getRight() { /*...*/ }
}

这更像是groupingBy而不是toMap:

public static <L, R> Map<L, Set<R>> pairsToMap(Stream<Pair<L, R>> pairs) {
return pairs.collect(Collectors.groupingBy(
Pair::getLeft, 
Collectors.mapping(Pair::getRight, Collectors.toSet())
));
}

groupingBy允许您指定进一步收集每个组的方法。在这种情况下,我们希望首先映射到右侧元素,然后映射到toSet

最新更新