web-dev-qa-db-ja.com

ArrayListのカスタムContainsメソッド

私はいくつかのオブジェクトを持っています

class A {
  private Long id; 
  private String name; 
  public boolean equals(Long v) {
     return this.id.equals(v);
  }
}

これらのオブジェクトのArrayList。私が欲しいのは、そのリストにオブジェクトのフィールドごとのオブジェクトが含まれているかどうかを確認できるようにすることです。例えば:

ArrayList<A> list = new ArrayList<A>(); if (list.contains(0L)) {...}

オーバーライドされたEqualsメソッドは役に立ちません。私が間違っているのは何ですか?ありがとうございました

[〜#〜] update [〜#〜]そして、hashcode()メソッドもオーバーライドする必要がありますか?

29
nKognito

以下に、どのように機能するかを示すコードを示します。

import Java.util.ArrayList;

class A {
  private Long id; 
  private String name; 

  A(Long id){
      this.id = id;
  }

    @Override
  public boolean equals(Object v) {
        boolean retVal = false;

        if (v instanceof A){
            A ptr = (A) v;
            retVal = ptr.id.longValue() == this.id;
        }

     return retVal;
  }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 17 * hash + (this.id != null ? this.id.hashCode() : 0);
        return hash;
    }
}

public class ArrayList_recap {
    public static void main(String[] args) {
        ArrayList<A> list = new ArrayList<A>(); 

        list.add(new A(0L));
        list.add(new A(1L));

        if (list.contains(new A(0L)))
        {
            System.out.println("Equal");
        }
        else
        {
            System.out.println("Nah.");
        }    
    }

}

まず、equals(Object o)メソッドのオーバーライドがあります。次に、hashCode()のオーバーライドもあります。また、equalsのinstanceof Aチェックにより、異なるオブジェクトを比較しようとしないことが保証されます。

これでうまくいくはずです!お役に立てば幸いです!乾杯:)

48
Vern

クラスでメソッドをオーバーライドしていません。オーバーライドするには、メソッドパラメータも同じタイプである必要があります。

そのはず

public boolean equals(Object o) {

}

あなたの場合のように

public boolean equals(Long o) {

 }

おそらくこれを行う必要があります

public boolean equals(Object o)
    {
        if (o == null) return false;
        if (o == this) return true; //if both pointing towards same object on heap

            A a = (A) o;
        return this.id.equals(a.id);
    }
8
Zohaib

私が間違っているのは何ですか?

オーバーライドしていません。あなたは過負荷です。

containsメソッドは、署名equals(Object)equalsメソッドを呼び出すため、追加したこの(新しい)メソッドは呼び出されません。

もう1つの問題は、equalsメソッドのcontainsのセマンティクスが間違っていることです。 containsメソッドは、thisをリストのメンバーである可能性のあるオブジェクトと比較する必要があります。リストにはLongオブジェクトが含まれていません。タイプAのオブジェクトが含まれます。

今、あなたはこれでうまくいくかもしれません...生のリストタイプを使用する場合...しかし、あなたがやろうとしているのはAPI契約の違反であり、悪い習慣です。より良い解決策は、リストの要素を明示的に繰り返しテストすることです。


また、hashcode()メソッドもオーバーライドする必要がありますか?

Ifequals(Object)をオーバーライドする場合は、hashcode()もオーバーライドする必要があります。

ここでは何の違いもありませんが、Aオブジェクトをハッシュされたデータ構造に配置する場合は不可欠です。そして、あなたは次の人があなたのコードで何をしようとしているのかわからないので、equals(Object)hashCode()が互換性のあるセマンティクスを持っていることを確認するのは良い習慣です。

7
Stephen C