我正在尝试创建一个搜索算法,将坐标对存储在名为HashSquareSpec的包装类中。为了避免重复,并维护插入顺序,我将每个HashSquareSpec插入到LinkedHashSet中。即使我重写了equals()方法和hashCode()方法,LinkedHashSet仍然接受两个HashSquareSpec对象 相同的坐标对。
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类
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;
}
}
和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 );
}
}
尽管有许多不同的hashCode变体和Eclipse等于和hashCode生成,但是 firedShots数据结构不断接受重复。我的代码出了什么问题?
答案 0 :(得分:3)
您走在正确的轨道上,覆盖hashcode
和equals
,除非您错误地覆盖HashSquareSpec
(和SquareSpec
)中的equals
method from Object
。参数必须是Object
。因为它未被覆盖,所以调用来自equals
的{{1}},它会比较对象引用以查看它们是否是同一个对象。他们不是,所以&#34;重复&#34;是允许的。
尝试:
Object
您还应该测试@Override
public boolean equals(Object other)
{
if(this.toString().equals(other.toString()))
return true;
else
return false;
}
是否为other
,然后确保null
的类型相同。
包含other
注释,以便编译器在方法实际上不覆盖任何内容时会抱怨。
答案 1 :(得分:0)
它仍在接受,因为您没有覆盖equals
方法。您需要覆盖boolean equals(Object)
。问题是您正在定义一种新方法,例如boolean equals(SquareSpec)
。
以下是LinkedHashSet#add(T)
最终调用的方法:
HashMap#put(K, V)
:
@Override public V put(K key, V value) {
if (key == null) {
return putValueForNullKey(value);
}
int hash = secondaryHash(key.hashCode());
HashMapEntry<K, V>[] tab = table;
int index = hash & (tab.length - 1);
for (HashMapEntry<K, V> e = tab[index]; e != null; e = e.next) {
if (e.hash == hash && key.equals(e.key)) {
preModify(e);
V oldValue = e.value;
e.value = value;
return oldValue;
}
}
如您所见,它使用hashCode
和equals(Object)
进行比较。