java
1package test; 2 3public class Sample { 4 5 private int num; 6 7 private String name; 8 9 public Sample(int num, String name) { 10 // TODO 自動生成されたコンストラクター・スタブ 11 12 this.num = num; 13 this.name = name; 14 15 } 16 public boolean equals(Object obj){ 17 if(obj == null){ 18 return false; 19 } 20 if(obj instanceof Sample){ 21 Sample s = (Sample) obj; 22 return s.num == this.num; 23 } 24 return false; 25 } 26 27} 28
上記のクラスが前提で
java
1 Sample a = new Sample(10,"a"); 2 3 Sample b = new Sample(10,"b"); 4 5 System.out.println(a.equals(b));
の処理をするとtrueが返ってきますが、どのような時に「==」でどんな時に「equals」を使用していいがわかりません。
使い分けはどのようにしたらいいのでしょうか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
ベストアンサー
参照型ではequals
プリミティブ型では==
ただし参照型でも「同じオブジェクトを指す」という条件にしたいなら==
投稿2017/03/01 13:56
編集2017/03/01 13:57総合スコア20651
0
例えばここに田中さんと田中さんがいたとします。
==
田中さん == 田中さん
とした場合、いくら名前が同じでも別人なのでこれはfalseとなります。==という比較は「実体そのものが同一であること」の判定です。
equals
田中さん.equals(田中さん)
とした場合、equals処理の中が「同名であるか」の判断処理であれば、これはtrueとなります。equalsという比較は「equalsの処理の中身で決まる」判定です。Stringであれば「同じ事が書いてあればOK」ですし、Integerであれば「同じ数字であればOK」です。
投稿2017/03/02 01:41
総合スコア9206
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
Sampleオブジェクトの同一性をnumを使って判定したい場合に、equalsメソッドをオーバーライドします。
つまり、アプリケーションを設計するうえで、Sampleのインスタンスは、numが等しいなら意味的に等しい場合。
equals()をオーバーライドする場合は、hshCode()もオーバーライドしなければなりません。
a.equals(b) ならば a.hshCode() == b.hashCode() でなければならない。
これは、ハッシュマップのキーにSampleを使用することがあるからです。
ただし、ハッシュマップのキーにSampleを使用するなら、注意点があります。
Sampleのnumがインスタンス生成後に変更されるなら、equals()の比較に使用できない。
理由は、HashMapに格納した後、aの値を変更すると取り出せなくなるから。
例を示します。
Java
1package test; 2 3import java.util.HashMap; 4import java.util.Map; 5 6public class MutableSample { 7 8 private int num; 9 private String name; 10 11 public MutableSample(int num, String name) { 12 this.num = num; 13 this.name = name; 14 } 15 16 @Override 17 public boolean equals(Object obj){ 18 if(!(obj instanceof MutableSample)){ 19 return false; 20 } 21 MutableSample s = (MutableSample) obj; 22 return s.num == this.num; 23 } 24 25 @Override 26 public int hashCode(){ 27 return this.num; 28 } 29 30 public void setNum(int num) { 31 this.num = num; // 変更可能 32 } 33 public int getNum() { 34 return this.num; 35 } 36}
setterを用意してnumの値を変更可能にしました。
実行例
Java
1 public static void main(String[] args) { 2 MutableSample a = new MutableSample(10,"a"); 3 MutableSample b = new MutableSample(10,"b"); 4 System.out.println("a == b : " + a.equals(b)); 5 6 Map<MutableSample,MutableSample> map = new HashMap<>(); 7 map.put(a,a); 8 System.out.println("map.containsKey(b) : " + map.containsKey(b)); 9 a.setNum(20); 10 System.out.println("map.containsKey(b) : " + map.containsKey(b)); 11 }
インスタンスaをマップに格納したのち、aのnumの値を変更しました。
aはマップの中から取り出せなくなります。
結論
equlas()内で、比較に使用するフィールドの値が変更可能かどうか?
インスタンスを生成してから変更されることがないなら、equals()で比較しても良い。
インスタンス生成後に変更されるなら、equals()の比較に使用できない。
equals()をオーバーライドするならhashCode()もオーバーライドしなければならない。
参考
edx: Software Construction in Java
###追記(意味的に同じにしたければ)
numとnameがともに等しければ、おなじSampleオブジェクトだと判定する、という回答が抜けていました。
Java
1package test; 2 3public class ImmutableSample { 4 5 private final int num; 6 private final String name; 7 8 public ImmutableSample(int num, String name) { 9 this.num = num; 10 this.name = name; 11 } 12 13 @Override 14 public boolean equals(Object obj){ 15 if(!(obj instanceof ImmutableSample)){ 16 return false; 17 } 18 ImmutableSample s = (ImmutableSample) obj; 19 return (s.num == this.num && s.name.equals(this.name)); 20 } 21 22 @Override 23 public int hashCode(){ 24 return (this.num + this.name.hashCode()); 25 } 26 27}
投稿2017/03/01 21:52
編集2017/03/01 22:41退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/03/02 00:14
2017/03/02 01:13
退会済みユーザー
2017/03/02 01:18
2017/03/02 01:19
退会済みユーザー
2017/03/02 01:34
2017/03/02 01:38
退会済みユーザー
2017/03/02 02:06
2017/03/02 02:09
退会済みユーザー
2017/03/02 04:56
0
上記のSampleクラス同士の比較の場合
aとbのハッシュコードが同一(同一インスタンス)であるかどうか確かめる時は==を用いる
aとbの持つnumが一致するかどうか確かめる場合は.equals()を用いる
投稿2017/03/01 14:19
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/03/02 00:52
退会済みユーザー
2017/03/02 02:15
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/03/04 03:52