I am trying to create a search algorithm that stores coordinate pairs in a wrapper class called HashSquareSpec. In order to avoid duplicates, and maintain insertion order, I am inserting each HashSquareSpec into a LinkedHashSet. Even though I have overridden the equals() method and hashCode() methods, the LinkedHashSet still accepts two HashSquareSpec objects with the same coordinate pairs.
public static void main(String [] args)
{
LinkedHashSet<HashSquareSpec> firedShots = new HashLinkedSet<HashSquareSpec>();
HashSquareSpec a = new HashSquareSpec(1,2);
HashSquareSpec b = new HashSquareSpec(2,2);
HashSquareSpec c = new HashSquareSpec(1,2);
HashSquareSpec d = new HashSquareSpec(3,2);
firedShots.add(a);
firedShots.add(b);
firedShots.add(c);
firedShots.add(d);
System.out.println(a.equals((SquareSpec)c));
Iterator l = firedShots.iterator();
while(l.hasNext())
{
System.out.println(l.next().hashCode());
}
}
Output:
true
38444474
38474265
38444474
38504056
HashSquare class
public class HashSquareSpec extends SquareSpec
{
public HashSquareSpec(int sx, int sy)
{
super(sx,sy);
}
public HashSquareSpec(String codeString)
{
super(codeString);
}
@Override
public int hashCode()
{
return this.toString().hashCode();
}
public boolean equals(HashSquareSpec other)
{
if(this.toString().equals(other.toString()))
return true;
else
return false;
}
}
and the super class of HashSquareSpec
public class SquareSpec {
public int x;
public int y;
public SquareSpec(int sx, int sy) {
this.x = sx;
this.y = sy;
}
public SquareSpec(String codeString) {
this.x = Integer.parseInt(codeString.substring(1,2));
this.y = Integer.parseInt(codeString.substring(3,4));
}
public String toString() {
return("(" + x + "," + y + ")");
}
public boolean equals(SquareSpec other) {
return (other.x == this.x &&
other.y == this.y );
}
}
Despite many different hashCode variations and Eclipse equals and hashCode generation, the firedShots data structure keeps accepting duplicates. What is wrong with my code?
You are on the right track, overriding hashcode
and equals
, except you are incorrectly overriding the equals
method from Object
in HashSquareSpec
(and SquareSpec
). The parameter must be an Object
. Because it's not overridden, equals
from Object
is called, which compares object references to see if they're the same object. They aren't, so the "duplicate" is allowed.
Try:
@Override
public boolean equals(Object other)
{
if(this.toString().equals(other.toString()))
return true;
else
return false;
}
You should also test if other
is null
and then ensure that other
is the same type.
Include the @Override
annotation so that the compiler will complain if the method doesn't actually override anything.