用于在Java中获取独特的集合元素对的习惯用法

时间:2011-03-25 04:03:36

标签: java collections set

是否有标准习惯用于获取给定Collection中每个唯一元素对的集合?

出于我们的目的,(a,b)的集合等价于(b,a),因此结果集中只应出现一个。

我可以看到如何使用基于配对元素实现hashCode和equals()的Pair类来构造这样的集合,但是我想知道是否还没有更标准的方法来生成这样的集合

2 个答案:

答案 0 :(得分:2)

就像你说的,带有哈希码&的Pair类。 等于已实施并置于 HashSet 中,可以完成您所需要的工作。我不知道JDK数据结构本身就是这样做的。

如果你想进一步概括它,你可以创建一个元组Tuple<T1,T2>并根据该元组HashSet<Tuple<T1,T2>>声明一个HashSet。然后为元组类型创建一个更通用的Equals / Hashcode方法。

以下是一个示例实现:

final class Pair<A, B> {
    private final A _first;
    private final B _second;

    public Pair(A first, B second) {
        _first = first;
        _second = second;
    }

    @Override
    public int hashCode() {
        int hashFirst = _first != null ? _first.hashCode() : 0;
        int hashSecond = _second != null ? _second.hashCode() : 0;
        return (hashFirst + hashSecond) * hashSecond + hashFirst;
    }

    @Override
    @SuppressWarnings("unchecked")
    public boolean equals(Object other) {
        if (other instanceof Pair) {
            Pair otherPair = (Pair) other;
            return this._first == otherPair._first //
                    || (this._first != null //
                            && otherPair._first != null && this._first.equals(otherPair._first)) //

                    && this._second == otherPair._second //
                    || (this._second != null //
                            && otherPair._second != null && this._second.equals(otherPair._second));
        }
        return false;
    }

    @Override
    public String toString() {
        return "(" + _first + ", " + _second + ")"; 
    }

    public A getFirst() {
        return _first;
    }

    public B getSecond() {
        return _second;
    }

答案 1 :(得分:0)

我为你创建了一个“懒惰”的实现,有点笼统(即可以列出任何大小的子集)。

在不需要同时在内存中的原始集(或所有子集)的所有元素的意义上它是懒惰的,但它并不是真正有效:在迭代器上调用next()仍然意味着迭代超过原始集合k-1次(如果k是所需的子集大小) - 幸运的是并非每次,大多数情况下我们在一个迭代器上只需要一个next()(至少在{与k(基本集的大小)相比,{1}}较小。当然,我们仍然需要在内存中拥有子集的n个元素。

我们还必须假设所有迭代器使用相同的顺序,只要基础集不会改变(并且我们不希望它在我们的一个迭代正在进行时改变)。如果k接口允许克隆迭代器,即在迭代器当前点处启动第二个迭代器,这将更容易。 (我们现在使用Iterator方法实现这一点。)对于有序映射,这应该更容易(等待更新)。

scrollTo

与我此处更大的代码示例一样,我的github存储库is findable中也是stackoverflow-examples