質問

私は期待どおりに動作する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)をオーバーライドする必要があります。代わりにこれを行うのは、あなたの署名equalsequals(Subclass)メソッドを実装しました。その結果、あなたのHashSetは平等のテストのためにequals(Object)で定義されたデフォルトのObjectの方法を使用しています。

デフォルトのequals(Object)の実装は、オブジェクトIDに基づいており、したがって、セットには、意味的に等しい一方で、同じオブジェクトではありません2 Stringsを追加する「ことができます」。

他のヒント

あなたは正しく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)は、あなたがする意図したものではない第二の方法を作成します。

2つのメタ・ポイントます:

まず、あなたがメソッドをオーバーライドしていると信じて毎回@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; }を付加価値があるが、それはそれの定期的な習慣を作るために本当に価値がないのです。

誰もがあなたが右public boolean equals(Object o)メソッドをオーバーライドする必要が言ったように、

私は、ほぼ同じ問題を抱えていました。しかし、それは十分ではありません!

そうでない場合は、Javaは全くpublic int hashCode()メソッドを呼び出すことはありません(あなたが行ったように)equalsをオーバーライドすることも必要です。

最初の推測は、それはあなたのequals(Subclass other)のように見えますが、あなたが望むように、equals(Object other)メソッドをオーバーライドするためにjava.lang.Object.equals()されるべきです。おそらくセットは、基礎となるequals()の実装を呼び出してます。

あなたのequalsメソッドが呼び出されることはありません。 equalsの署名は、それが(Objectを実装することを起こるどんなクラスを含む)equalsはなく、他のいくつかのクラスを取ることを要求する。

public boolean equals(Object other) {
    ...
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top