私は当初、ここで質問したいと考えていた理論に基づくベスト プラクティスの質問のテストとしてこれを開始しましたが、その過程で、java.Set クラスでいくつかの興味深い動作を見つけました。最初は、このアプローチの潜在的な落とし穴を知りたかったのですが、まったく機能しないことがわかったので、その理由を知りたいと思います。
アプリのデータベース オブジェクトのコンテナーであるオブジェクトがいくつかあります。オブジェクトはすべて一意integer id
の を持ち、hashCode()
とequals()
は整数 ID によって定義されます (ハッシュセットに格納するため)。
ええと、ハッシュセットに ID のみが指定されたオブジェクトが含まれているかどうかを確認する機能が必要でした。確かに、オブジェクトの新しいインスタンスを作成して、その方法を確認できました。でも、念のために、それを達成できるかどうかを確認したかったのです。もちろん、これはハッシュマップでも些細なことなので、これは重要な質問ではありません。楽しみと知識のためだけです。
そこで、クラスを作成し、オブジェクトのインスタンスではなく ,を呼び出そうとしcontains()
ました。integer
もちろん、Netbeans はこれについて楽しい警告を出します
Suspicious call to java.util.Collection.contains:
Given object cannot contain instances of int (expected Person)
エラーを無視してコードを実行したところ、Java が equals メソッドを呼び出していないことにショックを受けました。System.out.println()
検証のために equals メソッドに debugを配置しましたが、そうです、それは呼び出されていません。
以下に投稿されたコードでは、予想される出力は次のようになります (私の理論が正しかった場合):
Here Yes Here Yes
または(私の理論が間違っていた場合):
Here Yes Here No
ただし、出力は次のとおりです。
Here Yes No
equals メソッドが呼び出されていないことを証明する "No" の前に "Here" がないことに注意してください。
誰でも光を当てることができますか?equals()
効率のためにこれを追加するように常に言われました:
if (!(obj instanceof Person))
return false;
しかし、equals()
そのような状況で呼び出されなければ意味がありません。
SSCCE は次のとおりです。
御時間ありがとうございます。
import java.util.LinkedHashSet;
import java.util.Set;
/**
*
* @author Ryan
*/
public class Test7 {
public static void main(String[] args) {
class Person {
public final int id;
public final String name;
public Person(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public boolean equals(Object obj) {
System.out.println("Here");
if (this == obj)
return true;
if (obj instanceof Person)
return id == ((Person)obj).id;
else if(obj instanceof Integer)
return id == (Integer)obj;
else {
System.out.println("Returning False");
return false;
}
}
@Override
public int hashCode() {
return id;
}
}
Set<Person> set = new LinkedHashSet<Person>();
set.add(new Person(1, "Bob"));
set.add(new Person(2, "George"));
set.add(new Person(3, "Sam"));
if(set.contains(new Person(1, "Bob")))
System.out.println("Yes");
else
System.out.println("No");
if(set.contains(1))
System.out.println("Yes");
else
System.out.println("No");
}
}