I need to have a Set (HashSet) such that if I insert a pair (a, b) and if (b, a) is already in the set, the insertion would just be ignored. How to
As none of the answers mentions this approach, I'd like to add this approach:
public class UnorderedPair {
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 up = (UnorderedPair) 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;
}
}
Note that the general contract of the hashCode() and equals() should be followed:
hashCode() or equals() you usually have to also override the other method.equals return true for 2 objects, then the hashCode() method must return the same int for both the objects.hashCode() returns same int for 2 objects, then it's not necessarily true that the equals() method return true.The above implementation of equals() and hashCode() method ensures this.