Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java LinkedHashSet未删除重复项_Java_Coordinates_Hashcode_No Duplicates_Linkedhashset - Fatal编程技术网

Java LinkedHashSet未删除重复项

Java LinkedHashSet未删除重复项,java,coordinates,hashcode,no-duplicates,linkedhashset,Java,Coordinates,Hashcode,No Duplicates,Linkedhashset,我试图创建一个搜索算法,将坐标对存储在名为HashSquareSpec的包装类中。为了避免重复,并保持插入顺序,我将每个HashSquareSpec插入LinkedHashSet。尽管我已经重写了equals()方法和hashCode()方法,LinkedHashSet仍然接受两个具有 相同的坐标对 public static void main(String [] args) { LinkedHashSet<HashSquareSpec> firedShots = new

我试图创建一个搜索算法,将坐标对存储在名为HashSquareSpec的包装类中。为了避免重复,并保持插入顺序,我将每个HashSquareSpec插入LinkedHashSet。尽管我已经重写了equals()方法和hashCode()方法,LinkedHashSet仍然接受两个具有 相同的坐标对

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
以及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变体和eclipseequals以及hashCode生成,但是
firedShots数据结构不断接受重复项。我的代码有什么问题?

它仍然可以接受,因为您没有覆盖
equals
方法。您需要重写
布尔等于(对象)
。问题是您正在定义一个新方法,如
boolean equals(SquareSpec)

下面是
LinkedHashSet#add(T)
最终调用的方法:

HashMap#put(K,V):

@覆盖公共V输入(K键,V值){
if(key==null){
返回putValueForNullKey(值);
}
int hash=secondaryHash(key.hashCode());
HashMapEntry[]选项卡=表格;
int index=hash&(tab.length-1);
for(HashMapEntry e=tab[index];e!=null;e=e.next){
如果(e.hash==hash&&key.equals(e.key)){
预修改(e);
V oldValue=e.value;
e、 价值=价值;
返回旧值;
}
}

如您所见,它使用
hashCode
equals(Object)
进行比较。您在正确的轨道上,覆盖了
hashCode
equals
,除非您错误地覆盖了
HashSquareSpec
(和
SquareSpec
)。该参数必须是
对象
。因为它没有被重写,所以调用
对象
中的
等于
,比较对象引用以确定它们是否是同一对象。它们不是,所以允许“重复”

尝试:

您还应该测试
other
是否为
null
,然后确保
other
为同一类型


包括
@Override
注释,这样如果方法实际上没有重写任何内容,编译器就会抱怨。

这也不是一个好的
等于
实现;您应该执行
instanceof
检查。(例如,您的实现不是对称的,因为这将
等于
字符串
)@LouisWasserman非常正确,这就是为什么包含一个关于空检查和检查
其他
是否属于同一类型的句子的原因。
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 );
    }
  }
@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;
        }
    }
@Override
public boolean equals(Object other) 
{
  if(this.toString().equals(other.toString()))
    return true;
  else
    return false;
}