Javaでの比較
Javaの比較でよく使われるのは下記3つ。
-
==
演算子 -
equals
メソッド -
instansof
演算子
==
演算子について
javaの世界にはプリミティブ型と参照型が存在します。プリミティブ型の値を作ると直接メモリに値が書き込まれます。プリミティブ型にはint
やboolean
が存在します。==
はJavaのプリミティブ型の比較を行う時に使用します。
int a = 10;
int b = 10;
int c = 20;
System.out.println(a == b); //true
System.out.println(a == c); //false
また、Javaにはenumと呼ばれる列挙型があります。enumはクラスのように扱えますが、他のクラスでインスタンス化できず、enum内部で1度きりのみインスタンス化できます。つまりenumのインスタンスは、プログラムの中で一つということが保証されます。なのでenumも==
比較を行うことができます。==
はnullセーフなこと、enumの比較で型が違う時にコンパイルエラーで気づけることから、enumの比較では==
を使用することが推奨されています。
public enum WEEK {
SUNDAY("日曜日"),
MONDAY("月曜日"),
TUESDAY("火曜日"),
WEDNESDAY("水曜日"),
THURSDAY("木曜日"),
FRIDAY("金曜日"),
SATURDAY("土曜日");
private String name; // フィールドの定義
private WEEK(String name) { // コンストラクタの定義
this.name = name;
}
}
Week week = Week.SUNDAY;
System.out.println(week == Week.SUNDAY); //true
System.out.println(week == Week.SATURDAY); //false
equalsメソッドについて
equalsメソッドは文字列やオブジェクトなど参照型の比較の時に使用します。
なぜ文字列やオブジェクトの比較で==
を使ったらダメなのでしょうか?
答えは文字列やオブジェクトの比較で==
を使用すると参照型変数が同じインスタンスを参照しているかどうかを判定(等値判定
)してしまうからです。Javaで用意されている参照型のequalsメソッドを使用した場合は、参照先インスタンスの内容が一致するかどうか(等価判定
)を判定します。
List<String> test1 = Arrays.asList("a","b","c");
List<String> test2 = Arrays.asList("a","b","c");
System.out.println(test1 == test2); // false
System.out.println(test1.equals(test2)); // true
equalsを使う上での注意点は2つあります。
1つ目はnull安全でないことです。下記のように左辺にnullが入っていた場合はNullPointerException
が発生してしまいます。
String a = null;
String b = "test";
System.out.println(a.equals(b)); // NullPointerException
2つ目は、Objectクラスに定義されているequalsメソッドは、以下のように自身のオブジェクト(this)と、引数に渡された参照先のオブジェクトの等値判定のみが行われています。
public boolean equals(Object obj){
return(this == obj);
}
なので自分たちが定義してあげたクラスのオブジェクトで等価判定をしたい場合はequalsメソッドをオーバーライドしてあげる
必要があります。
public class Person{
String name;
// コンストラクタ
public Person(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
// Personにキャストして、nameの値が同じか調べる
return name.equals(((Person)obj).name);
}
}
Person test1 = new Person("test");
Person test2 = new Person("test");
System.out.println(test1 == test2); // false
System.out.println(test1.equals(test2)); // true
最後に余談ですが、Lombokでは@EqualsAndHashCode
というアノテーションが用意されており、equalsメソッドを自動でオーバーライドしてくれて、等価判定
を行えます。
@EqualsAndHashCode
public class Person{
String name;
// コンストラクタ
public Person(String name) {
this.name = name;
}
}
Person test1 = new Person("test");
Person test2 = new Person("test");
System.out.println(test1 == test2); // false
System.out.println(test1.equals(test2)); // true
instansof 演算子について
12.12記載予定