我需要一个Set(HashSet),这样如果我插入一对(a, b)
并且如果(b, a)
已经在集合中,则插入将被忽略。如何在Java中执行此操作?
非常感谢!
答案 0 :(得分:7)
嗯,这取决于hashCode()
课程的equals()
和Pair
方法。他们需要忽略秩序。
Set
本身就是一个忽略了相等顺序的类的好例子 - 你可以查看AbstractSet
的代码。如果即使在相等比较之外,对的顺序也无关紧要,您只需在集合中存储HashSet
s(每个都有两个元素)。最好将其包装在数据类型中:
public class UnorderedPair<T> {
private final Set<T> set;
public UnorderedPair(T a, T b) {
set = new HashSet<T>();
set.add(a);
set.add(b);
}
public boolean equals(Object b) {
//...delegate to set
}
public int hashCode() {
return set.hashCode();
}
}
答案 1 :(得分:3)
final class Pair<T> {
private final Set<T> elements = new LinkedHashSet<T>();
Pair(T a, T b) {
elements.add(a);
if (!elements.add(b))
throw new IllegalArgumentException();
}
@Override
public int hashCode() {
return elements.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof Pair<?>))
return false;
return elements.equals(((Pair<?>) obj).elements);
}
}
答案 2 :(得分:2)
定义一个类Pair
,其equals
和hashCode
方法基于a
和b
的方式,顺序为a
}和b
无关紧要,并使用HashSet
。
答案 3 :(得分:0)
重写equals()
类的hashCode()
和Pair
方法,将(a,b)和(b,a)视为相等。
答案 4 :(得分:0)
由于没有答案提到这种方法,因此我想添加这种方法:
public class UnorderedPair<T> {
final T first, second;
public UnorderedPair(T first, T second) {
this.first = first;
this.second = second;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof UnorderedPair))
return false;
UnorderedPair<T> up = (UnorderedPair<T>) o;
return (up.first == this.first && up.second == this.second) ||
(up.first == this.second && up.second == this.first);
}
@Override
public int hashCode() {
int hashFirst = first.hashCode();
int hashSecond = second.hashCode();
int maxHash = Math.max(hashFirst, hashSecond);
int minHash = Math.min(hashFirst, hashSecond);
// return Objects.hash(minHash, maxHash);
// the above line also works but I tend to avoid this to avoid unnecessary auto-boxing
return minHash * 31 + maxHash;
}
}
请注意,应遵守hashCode()
和equals()
的一般合同:
hashCode()
或equals()
,则应也应覆盖另一种方法。equals
返回2个对象的true
,则hashCode()
方法应该为两个对象返回相同的int
。hashCode()
对于2个对象返回相同的int
,则equals()
方法返回true
不一定是正确的。以上equals()
和hashCode()
方法的实现确保了这一点。