Java

Javaの文字列比較の最大の謎「==」と「equals」の違いとは?

※アフィリエイト広告を利用しています。

「Javaで文字列の比較が思ったとおりに動かない」
「Javaの文字列比較では==ではなく、equalsを使うのはなぜ?」

Javaを勉強し始めた人の中にはこのような疑問を持つ方もいるのではないでしょうか?

今回の記事ではそんなJavaの文字列比較について、現役エンジニアがわかりやすく解説していきます!

この記事を読むことで、Javaの文字列比較ではなぜ「==」ではなく、「equals」メソッドを使わなければならないのか?ということがわかります。

これからJavaを学んでいきたい人や文字列方の比較ができるようになりたい方はぜひこの記事を読んでみてください!

Javaで「==」を使って文字列比較をするとどうなるか?

Javaではif文などの条件分岐の際に「==」を使って比較をすることができます。

例えば次のように2つの数字が同じかどうか判定する際には「==」で比較します。

public class Main {
    public static void main(String[] args) {
        // 変数に10を代入
        int num1 = 10;
        int num2 = 10;

        System.out.println("変数の値は「" + num1 + "」と「" + num2 + "」です。");

        // 2つの変数を==を使って比較する
        if (num1 == num2) {
            System.out.println("2つの変数の値は同じです。");
        } else {
            System.out.println("2つの変数の値は違います。");
        }
    }
}

実行結果は次のとおりです。

変数の値は「10」と「10」です。
2つの変数の値は同じです。

では次に文字列を「==」を使って比較してみるとどうなるでしょうか?

public class Main {
    public static void main(String[] args) {
        // 変数にHelloを代入
        String str1 = new String("Hello");
        String str2 = new String("Hello");

        System.out.println("変数の値は「" + str1 + "」と「" + str2 + "」です。");

        // 2つの変数を==を使って比較する
        if (str1 == str2) {
            System.out.println("2つの変数の値は同じです。");
        } else {
            System.out.println("2つの変数の値は違います。");
        }
    }
}

実行結果は次のようになります。

変数の値は「Hello」と「Hello」です。
2つの変数の値は違います。

このようにstr1とstr2には同じ「Hello」という文字列が格納されているのにも関わらず、結果としては「違う」と出力されていることがわかります。

Javaで2つの文字列が同じかどうか比較するためには、「==」で比較することができません。

Javaで文字列の比較にはequalsメソッドを使おう!

Javaにおいて、文字列の比較で「==」を使うと同じ文字列であっても違うと判定されてしまうことがわかりました。

Javaでは2つの文字列が同じかどうか比較する際には、equalsメソッドを使う必要があります。

equalsメソッドは次のように使います。

public class Main {
    public static void main(String[] args) {
        // 変数にHelloを代入
        String str1 = new String("Hello");
        String str2 = new String("Hello");

        System.out.println("変数の値は「" + str1 + "」と「" + str2 + "」です。");

        // 2つの変数をequalsメソッドを使って比較する
        if (str1.equals(str2)) {
            System.out.println("2つの変数の値は同じです。");
        } else {
            System.out.println("2つの変数の値は違います。");
        }
    }
}

このプログラムの実行結果は次のようになります。

変数の値は「Hello」と「Hello」です。
2つの変数の値は同じです。

このようにequalsメソッドを使うことで、2つの文字列を比較することができました!

nullと文字列を比較すると例外が発生するから要注意!

equalsメソッドを使って、文字列を比較することができますが、注意点もあります。

それは比較する変数にnullが入っていた場合に、「NullPointerException」が発生してしまうことです。

public class Main {
    public static void main(String[] args) {
        // 変数にnullとHelloを代入
        String str1 = null;
        String str2 = new String("Hello");

        System.out.println("変数の値は「" + str1 + "」と「" + str2 + "」です。");

        // 2つの変数をequalsメソッドを使って比較する
        if (str1.equals(str2)) {
            System.out.println("2つの変数の値は同じです。");
        } else {
            System.out.println("2つの変数の値は違います。");
        }
    }
}

str1にはnullを入れました。

これを実行すると次のように例外が発生します。

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because "str1" is null
	at Main.main(Main.java:11)

ではこの例外が発生しないためにはどうすれば良いでしょうか?

この記事では2つの対策を解説します。

文字列比較のNull対策1:nullチェック

対策の一つ目は比較をする前にnullチェックを行うことです。

次のプログラムを見てください。

public class Main {
    public static void main(String[] args) {
        // 変数にHelloを代入
        // String str1 = new String("Hello");
        String str1 = null;
        String str2 = new String("Hello");

        System.out.println("変数の値は「" + str1 + "」と「" + str2 + "」です。");

        // 比較をする前にnullチェックを行う
        if (str1 == null) {
            System.out.println("str1がnullです。");

            // プログラムを終了する
            return;
        }

        // 2つの変数をequalsメソッドを使って比較する
        if (str1.equals(str2)) {
            System.out.println("2つの変数の値は同じです。");
        } else {
            System.out.println("2つの変数の値は違います。");
        }
    }
}

equalsメソッドを使った文字列比較の前にstr1がnullかどうかチェックをします。

str1がnullだった場合は、プログラムを終了し、null出なければ比較を行います。

実行結果は次のようになります。

変数の値は「null」と「Hello」です。
str1がnullです。

文字列比較のNull対策2:比較順序の考慮をする

対策の2つ目は比較の順序を考慮することです。

nullが入っていて、例外が発生するのは、メソッドを呼び出した変数がnullの場合です。

つまり次のような比較をしている場合、str1がHelloでstr2がnullの場合でも例外は発生しません。

str1.equals(str2)

プログラムの中で文字列比較を行う際に、比較する変数にnullが入る可能性が限りなく0に近い方のequalsメソッドを呼び出すことで、例外が発生する可能性を下げることができます。

例えば、ユーザーによって入力された値と定数クラスの中で定義している文字列を比較する場合を考えてみましょう。

ユーザーによって入力される値は場合によってはnullが入ることがあり得そうです。

しかし定数クラスで定義されている文字列はnullが入る可能性はほぼありません。

その場合は定数クラスの定数.equals(ユーザー入力値)とすることで、例外を発生させてしまう可能性を下げることができます。

==とequalsの文字列比較は何が違うのか?

ここからは「==」と「equals」の何が違うのかということについて解説していきます。

例えば東京都に住む田中太郎さんと大阪府に住む田中太郎さんがいたとします。

そして2人の名前は同じかどうか判定したいとしましょう。

今回の例で行くと2人とも同じ名前なので、答えは「はい」になります。

そしてJavaでいう「==」を使った比較は、住所を比べているようなものなのです。

すると東京都と大阪府を比べてしまうため、2人の名前が同じであるにも関わらず答えは「いいえ」になってしまいます。

それに対してequalsメソッドはしっかりと名前を比べています。

つまり「田中太郎」と「田中太郎」を比べます。

そのため答えは「はい」になります。

これをプログラムやコンピュータ的な用語を使うとメモリ上の場所(参照)とか実際のデータとなります。

参照やメモリを使った説明は他の記事でも解説されていますので、気になる方は読んでみてください。

とにかく「==」と「equals」の違いをまとめると次のようになります。

  • 「==」は住所を比べているようなもの
  • 「equals」は名前自体を比較する

効率よくプログラミングを学習するためには

効率よくプログラミングを学習して、エンジニアになりたい人はプログラミングスクールの活用も検討してみてください。

プログラミングスクールでは基礎から実践的な内容まで学べるカリキュラムが整っているため効率よくJavaのスキルを獲得することができます。

また現役エンジニアに質問できる環境を手に入れることができるため、学習中に詰まったところやわからないところを聞くことが可能です。

中でもおすすめのプログラミングスクールはFreeksです。

Freeksは月額制でプログラミングを学べるスクールで、現役エンジニアに質問できる環境を手に入れることができます。

月額制なので、嫌になったらすぐに辞めることができますし、転職や就職のサポートも行なっているのでプログラミングを学んでエンジニアになりたい人にはおすすめです。

Freeksでは無料カウンセリングを実施していて、

  • 悩みが解決した
  • 将来のプランができた
  • IT知識がついた

などといった理由から満足度96%の実績があります。

無料カウンセリングに参加することはノーリスクなので、少しでも気になる人は気軽にチャレンジしてみてください。

無料カウンセリングにはこちらのリンクから簡単に申し込むことができます!
Freeks公式サイトから無料カウンセリングに申し込む

-Java