9

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$
4

6 に答える 6

22

をオーバーライドする必要がありますequals(Object)。これを行う代わりに、equalssignatureを使用してメソッドを実装しましたequals(Subclass)。したがって、は、同等性テスト用に定義されHashSetたデフォルトの方法を使用しています。equals(Object)Object

デフォルトのequals(Object)実装はオブジェクトIDに基づいているため、このセットを使用するStringと、意味的には同じであるが同じオブジェクトではない2つのを追加できます。

于 2009-11-02T20:36:55.957 に答える
6

を正しくオーバーライドしませんでした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番目のメソッドを作成します。

于 2009-11-02T20:37:32.703 に答える
3

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; }価値がありません。

于 2009-11-04T01:03:02.577 に答える
2

public boolean equals(Object o)誰もが正しい方法をオーバーライドする必要があると言ったので、私はほとんど同じ問題を抱えていました。しかし、それだけでは十分ではありません。

(あなたがしたように)オーバーライドすることも必要public int hashCode()です、さもなければ、javaはequalsメソッドをまったく呼び出さないでしょう。

于 2012-09-06T19:21:05.880 に答える
0

equalsメソッドが呼び出されることはありません。のシグニチャでは、他のクラス(実装しているクラスを含む)ではなく、equalsを使用する必要があります。Objectequals

public boolean equals(Object other) {
    ...
}
于 2009-11-02T20:40:14.757 に答える
0

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

于 2009-11-02T20:38:08.100 に答える