我需要一个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
答案 0 :(得分:4)
使用适当的Set<Edge>
和Edge
方法定义类型equals
的{{1}}将用于存储此信息。
您的输入hashCode
在班级A->B
中有效。该类有两个字段,我们称之为源和目标。此措辞将与您使用的箭头(定向与无向图)一致。
像这样的教程http://tutorials.jenkov.com/java-collections/hashcode-equals.html解释了Edge
和equals
的基础知识。在您的情况下,它很重要,hashCode
Edge
被视为等同于A->B
Edge
(同样,图表中的路线...... {{1} })
答案 1 :(得分:1)
例如,让Vertex
成为Comparable<Vertex>
根据重新建议,您应该创建Edge
课程,其中equals
和hashCode
会被覆盖:
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来说有点罗嗦,但这确实有效。