13

クラスがあるとしましょう

public class Data{
    public int k;
    public int l;
    public Data(int k, int l){
      this.k = k; 
      this.l = l;
    }
    public boolean equals(Date m){
      if(this.k == m.k && this.l = m.l)
           return true;
      return false;
    }
}

そして、いくつかの Data オブジェクトを ArrayList に追加します。

ArrayList<Data> holder = new ArrayList<Data>;
Data one = new Data(0,0);
Data two = new Data(0,4);
Data three = new Data(0,5);

indexOf がこれを見つけられないのはなぜですか?:

holder.indexOf(new Data(0,4)); //returns -1

配列リスト全体を自分で調べるよりも indexOf の方が優れていますか? それとも私は何かを逃していますか。

4

4 に答える 4

24

indexOf()メソッドはリスト全体を通過しますJava 7 ソース コードからの抜粋を次に示します。

public int indexOf(Object o) {
    if (o == null) {
        for (int i = 0; i < size; i++)
            if (elementData[i]==null)
                return i;
    } else {
        for (int i = 0; i < size; i++)
            if (o.equals(elementData[i]))
                return i;
    }
    return -1;
}

自分で書くよりも、Java に任せたほうがよいでしょう。equalsメソッドが必要なオブジェクトを見つけるのに十分であることを確認してください。また、オーバーライドすることもhashCode()できます。

あなたのequals方法を書き出すことはしませんが、少なくとも次のことをお勧めします。

  • null をチェックする
  • 比較しているインスタンスが同じかどうかをテストします
  • する必要はありませんif(boolean_expr) { return true; }。ブール式を返すだけです。
  • メソッドを実際にオーバーライドしていることを確認してください。equalsその署名には、Objectではなくパラメーターが必要Dateです。
于 2013-07-08T04:04:01.877 に答える
11

メソッドの署名equalsが間違っています。equalsinをオーバーライドしているのではなくObject、オーバーロードしているだけです。

equalsのメソッドの動作をオーバーライドするにObjectは、署名が の署名と正確に一致する必要がありますObject。これを試して:

public boolean equals(Object o) {
    if(!(o instanceof Data)) return false;
    Data other = (Data) o;
    return (this.k == other.k && this.l == other.l);
}

さらに、他の人が示唆したようにhashCode、マップベースのコレクションでオブジェクトが正しく機能するように、メソッドもオーバーライドすることをお勧めします。

于 2013-07-08T04:36:25.530 に答える
-2

慣例により、 equals をオーバーライドするときにもハッシュコードをオーバーライドする必要があります

ほとんどの場合、indexOf は hashcode メソッドを使用して、equals ではなくオブジェクトに一致することがわかります。

Eclipse を使用してコードを編集する場合、Eclipse は「ソース」メニューから適切な equals および hashcode メソッドを生成します。

于 2013-07-08T04:12:40.513 に答える