簡體   English   中英

HashSet允許重復

[英]HashSet allows duplicates

我似乎無法使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$

您需要重寫equals(Object) 而不是這樣做,您實現了帶有簽名equals(Subclass)equals方法。 因此你HashSet使用的是默認equals(Object)方法定義Object平等的測試。

默認的equals(Object)實現基於對象標識,因此該集合“允許”您添加兩個String ,這些語義在語義上均相等,但不是同一對象。

您沒有正確重寫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)創建了第二個方法,該方法不是您想要的。

兩個元點:

首先,養成每次您相信要覆蓋方法時都使用@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; } if (object == this) { return true; }但養成習慣確實不值得。

我遇到了幾乎相同的問題,因為每個人都說您需要重寫正確的public boolean equals(Object o)方法。 但這還不夠!

還必須重寫public int hashCode() (如您所做的那樣),否則,java根本不會調用equals方法。

首先猜測,看起來您的equals(Subclass other)應該equals(Object other) ,以便根據需要重寫java.lang.Object.equals()方法。 該集合可能正在調用底層的equals()實現。

您的equals方法永遠不會被調用。 equals的簽名要求它接受一個Object ,而不是其他一些類(包括碰巧實現equals任何類)。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM