java 或 groovy 中包含整数的集合之间的相似性

Similarity between Sets containing Integers in java or groovy

我有 HashSet<Integer> AB 我想比较它们的相似程度的数值(例如,如果 90% 的 AB 相同)。在 java 或 groovy 中执行此操作的最佳(最快)方法是什么?

我天真的方法是从 AB 中获取所有相等的元素,然后将它们的大小除以 A 的原始大小。有什么原因(例如速度)为什么这不能正常工作吗?一般来说,我更喜欢任何已经实现的方式来获得相似性。

注:比较1, 212应该是0%的相似度。

计算大小为 M 和 N 的 2 个任意 HashSet 的相似度的唯一方法是选择最小的一个并检查其元素是否存在于更大的一个中。 JDK中没有这样的方法。如果您正在寻找最快的解决方案,请自己编写:

int count = 0;
for (E element : smallSet) {
    if (bigSet.contains(element) {
       count++;
    }
}

如果你不太关心性能和额外的内存,你可以使用

int count = new HashSet(smallSet).retainAll(bigSet);

或来自 Guava 库的类似方法 Sets#intersection(Set, Set)

正如 Adam 所建议的,循环是找到交集大小的最有效方法

public static int intersectionsCount(Set set1, Set set2) {
    if (set2.size() < set1.size()) return intersectionsCount(set2, set1);
    int count = 0;
    for (Object o : set1)
        if (set2.contains(o)) count++;
    return count;
}

public static double commonRatio(Set set1, Set set2) {
    int common = intersectionsCount(set1, set2);
    int union = set1.size() + set2.size() - common;
    return (double) common / union; // [0.0, 1.0]
}