5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

開発力強化Advent Calendar 2022

Day 3

Javaの比較いろいろ

Last updated at Posted at 2022-12-11

Javaでの比較

Javaの比較でよく使われるのは下記3つ。

  • ==演算子
  • equalsメソッド
  • instansof 演算子

==演算子について

javaの世界にはプリミティブ型と参照型が存在します。プリミティブ型の値を作ると直接メモリに値が書き込まれます。プリミティブ型にはintbooleanが存在します。==は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記載予定

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?