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!!」と表示された。