寻找合适的集合 - 双向唯一对

时间:2014-06-18 10:36:35

标签: java collections

我需要一个Java集合,它代表以下数据结构: 如果我得到以下输入,我需要按如下所述存储它们:

A-> B //应存储

A-> C //应存储

A-> B //不应再被允许(存储),因为它已经在集合中

B-> A //也不应该被允许(存储)为A-> B已经在集合中

C-> B //应存储

D-> C //应存储

我希望你明白这一点。

我已经尝试了HashMap<Set<String>, Set<String>>但是变异的键集出错了,如下所述:https://stackoverflow.com/a/2393748/2346207

3 个答案:

答案 0 :(得分:4)

使用适当的Set<Edge>Edge方法定义类型equals的{​​{1}}将用于存储此信息。

您的输入hashCode在班级A->B中有效。该类有两个字段,我们称之为源和目标。此措辞将与您使用的箭头(定向与无向图)一致。

像这样的教程http://tutorials.jenkov.com/java-collections/hashcode-equals.html解释了Edgeequals的基础知识。在您的情况下,它很重要,hashCode Edge被视为等同于A->B Edge(同样,图表中的路线...... {{1} })

答案 1 :(得分:1)

例如,让Vertex成为Comparable<Vertex>

根据重新建议,您应该创建Edge课程,其中equalshashCode会被覆盖:

public class Edge {
    Vertex first, second;
    public Edge (Vertex first, Vertex second) {
        int order = first.compareTo(second);
        this.first = (order > 0) ? first : second;
        this.second = (order > 0) ? second : first;
    }
    @Override
    public boolean equals (Object o) {
        if (!(o instanceof Edge))
            return false;
        Edge other = (Edge)o;
        return other.first.equals(first) && other.second.equals(second);
    }
    @Override
    public int hashCode() {
        return first.hashCode() * 31 + second.hashCode();
    }
}

first <= second总是

,将忽略排序

答案 2 :(得分:1)

您也可以仅使用java.util默认值,例如作为集合集:

HashSet<HashSet<String>> h = new HashSet<HashSet<String>>();

h.add(new HashSet<String>(Arrays.asList("A", "B")));
h.add(new HashSet<String>(Arrays.asList("B", "A"))); // will be ignored
h.add(new HashSet<String>(Arrays.asList("B", "C"))); // ok, new member

在Java中对于oneliner来说有点罗嗦,但这确实有效。