JavaのSetを使ってみて、contains()メソッドで少しはまったことがあるのでメモしておく。
まず、コレクションに入れるためのこんなクラスを作った。
public class PersonInfo{ public final int id; public final String name; public PersonInfo(int id,String name){ this.id = id; this.name = name; } @Override public boolean equals(Object obj) { if( obj != null && obj instanceof PersonInfo ){ final PersonInfo target = (PersonInfo)obj; return ( target.id == this.id ); } return false; } }
そして、始めはArrayListに入れようとして、次のようなコードを書いた。
List<PersonInfo> list = new ArrayList<PersonInfo>(); list.add(new PersonInfo(1,"hoge")); if( list.contains(new PersonInfo(1,"foo"))){ System.out.println("contains!!"); }
実行すると、当然「contains!!」と表示される。
それで、次はArrayListをHashSetに変えてみた。
Set<PersonInfo> mySet = new HashSet<PersonInfo>(); mySet.add(new PersonInfo(1,"hoge")); if( mySet.contains(new PersonInfo(1,"foo"))){ System.out.println("contains!!"); }
すると、今度は何も表示されなくなってしまった。
ここで何故なのか一瞬とまどったが落ち着いて考えるとHashSetのcontains()はhashCode()の値で判定することを思い出した。
今のクラスはhashCode()がオーバーライドされていなかった。
そこで、
public class PersonInfo{ // 略 @Override public int hashCode() { return id; } }
のようにしてhashCode()をオーバーライドし、先のコードを実行すると、無事「contains!!」と表示された。