hashset允许重复

q5lcpyga  于 2021-07-05  发布在  Java
关注(0)|答案(6)|浏览(308)

我好像找不到 HashSet 示例按预期工作。我使用的代码如下:

import testing.Subclass;
import java.util.HashSet;

public class tester {
  public static void main(String[] args) throws Exception {
    HashSet<Subclass> set = new HashSet<Subclass>();
    set.add(new Subclass("007812"));
    set.add(new Subclass("007813"));
    System.out.println("Set size " + set.size());
    set.add(new Subclass("007812"));
    System.out.println("Set size " + set.size());

    for(Subclass sub : set) {
      System.out.println(" sub acctNbr " + sub.getAcctNbr());
    }
  }
}

子类

public class Subclass implements Comparable<Subclass> {

  public Subclass(String acctNbr) {
    this.acctNbr = acctNbr;
  }
  private String acctNbr;
  public String getAcctNbr() {
    return this.acctNbr;
  }
  public int compareTo(Subclass other) {
    return this.getAcctNbr().compareTo(other.getAcctNbr());
  }

  public boolean equals(Subclass other) {
    if(other.getAcctNbr().equals(this.getAcctNbr()))
      return true;
    else
      return false;
  }
  public int hashCode() {
    return acctNbr.hashCode();
  }
}

此代码输出

sross@sross-workstation:~/Documents$ javac testing/Subclass.java
sross@sross-workstation:~/Documents$ javac tester.java
sross@sross-workstation:~/Documents$ java tester
Set size 2
Set size 3
 sub acctNbr 007812
 sub acctNbr 007812
 sub acctNbr 007813
sross@sross-workstation:~/Documents$
5q4ezhmt

5q4ezhmt1#

乍一看,你的 equals(Subclass other) 应该是的 equals(Object other) 为了覆盖 java.lang.Object.equals() 方法,如你所愿。可能是集合在调用底层 equals() 实施。

plupiseo

plupiseo2#

我遇到了几乎相同的问题,因为每个人都说你需要推翻权利 public boolean equals(Object o) 方法。但这还不够!
也有必要覆盖 public int hashCode() (正如您所做的),否则,java不会调用 equals 方法。

bejyjqdl

bejyjqdl3#

你需要重写 equals(Object) . 你没有这样做,而是实现了一个 equals 带签名的方法 equals(Subclass) . 因此你的 HashSet 正在使用默认值 equals(Object) 上定义的方法 Object 平等测试。
默认值 equals(Object) 实现基于对象标识,因此集合“允许”您添加两个 String 在语义上相等的s不是同一个对象。

pvcm50d1

pvcm50d14#

您没有正确覆盖 Object.equals() .

@Override
public boolean equals(Object other) {
    if ((other == null) || !(other instanceof Subclass)) {
        return false;
    }
    return ((Sublcass) other).getAcctNbr().equals(this.getAcctNbr());
}

方法 boolean equals(Subclass other) 创建第二个方法,但这不是您想要做的。

piv4azn7

piv4azn75#

两个要点:
首先,养成使用的习惯 @Override 每次你相信你正在重写一个方法。这将导致示例代码无法编译,从而导致您发现问题。
第二,如果您使用的是ide,并且它没有为您突出显示一个漂亮的粗体警告,那么它的配置是错误的!你应该修好它!
如果你不使用ide——你真的,真的应该使用。你一打字 public boolean equals(Subclass other) ,文本将改变颜色并显示警告,告诉您可能的问题是什么。
顺便说一下 equals() 我的观点是:

@Override public boolean equals(Object object) {
  if (object instanceof Subclass) {
    Subclass that = (Subclass) object;
    return this.anInt == that.anInt
        && this.aString.equals(that.aString); // for example
  }
  return false;
}

在某些情况下,预先准备一个 if (object == this) { return true; } 但是养成一个固定的习惯是不值得的。

rfbsl7qr

rfbsl7qr6#

永远不会调用equals方法。签字人 equals 需要一个 Object ,而不是其他类(包括碰巧实现的任何类) equals ).

public boolean equals(Object other) {
    ...
}

相关问题