Java列表:使用lambda表达式获得具有成对不同键的Pairs数量

时间:2015-05-21 08:07:23

标签: list lambda stream hashmap

我有一个键值对列表,我想过滤一个列表,其中每个键参数只出现一次。

这样的列表例如{Pair(1,2), Pair(1,4), Pair(2,2)}变为{Pair(1,2), Pair(2,2)}

Pair过滤掉并不重要,因为我只需要大小 (也许有不同的方法来获得成对不同键值的对数量?)。

这一切再次发生在一系列列表(键值对)的另一个流中,并且它们全部加起来。

我基本上想要一个hashmap中的冲突量。

我希望你明白我的意思;如果没有请问。

public int collisions() {
    return Stream.of(t)
            .filter(l -> l.size() > 1)
            .filter(/*Convert l to list of Pairs with pairwise different Keys*/)
            .mapToInt(l -> l.size() - 1)
            .sum();
}

编辑:

    public int collisions() {
    return Stream.of(t)
            .forEach(currentList = stream().distinct().collect(Collectors.toList())) //Compiler Error, how do I do this?
            .filter(l -> l.size() > 1)
            .mapToInt(l -> l.size() - 1)
            .sum();
}

如果密钥相同,我覆盖了对的等于返回true,所以现在我可以使用distinct来删除"重复" (具有相同键的对)。 是否有可能在forEach中用相同的List替换currentElement"区别"?如果是这样,怎么样?

此致 Claas M

2 个答案:

答案 0 :(得分:0)

不要使用流。将列表转储到带有自定义比较器的SortedSet中并区分大小:

List<Pair<K, V>> list; // given this

Set<Pair<K, V>> set = new TreeSet<>(list, (a, b) -> a.getKey().compareTo(b.getKey())).size();
set.addAll(list);
int collisions = list.size() - set.size();

如果密钥类型不具有可比性,请相应地更改比较器lambda。

答案 1 :(得分:0)

我不确定您是否希望每个列表中的冲突量或所有列表中的冲突量之前合并为单个冲突。我假设了前者,但如果是后者,那么这个想法并没有太大改变。

这是如何使用allowBindings:false

完成的
Streams

int collisions = Stream.of(lists) .flatMap(List::stream) .mapToInt(l -> l.size() - (int) l.stream().map(p -> p.k).distinct().count()) .sum(); 会为您提供一个包含单个元素的Stream.of(lists)。 然后你Stream<List<List<Pair<Integer, Integer>>,这样你就有了flatMap

从那里开始,每个列表Stream<List<Pair<Integer, Integer>>通过用其包含的密钥(mapToInt)减去其原始大小和唯一对的元素数量。{/ p>

最后,您调用sum来获得总体冲突量。

请注意,您可以使用l.stream().map(p -> p.k).distinct().count()来摆脱演员表,但mapToLong必须是collisions(如果每个列表都有很多“碰撞”,这可能会更正确“)。

例如给出输入:

long

当第一个列表中有1个碰撞,第二个列表中有1个碰撞,第三个列表中有2个碰撞时,它将输出4。