【Java入門】文字列(String)を比較する方法(「==」と「equals」)

Java言語で文字列の値を比較したことがあるかと思います。Javaで文字列を比較するにはequalsを使う方法がありますが

  • ==を使うのはだめなの?
  • なぜequalsメソッドを使うの?

と言った声をお聞きします。文字列の比較についてわかりやすく解説をしていきます。この記事を見ればJava言語で文字列を比較した結果がどうなるかがわかります!

文字列の比較

equalsメソッドで比較する

まずは文字列の比較方法であるStringクラスのequalsメソッドを使って文字列の比較をしてみましょう。

サンプルプログラム:

public class Main {

	public static void main(String[] args) {
		String foo = "foo";
		String bar = "bar";

		if (foo.equals(bar)) {
			System.out.println("fooとbarは一緒です。");
		} else {
			System.out.println("fooとbarは違います。");
		}
	}

}

実行結果:

fooとbarは違います。

equlasメソッドは、引数に比較先となる文字列を指定することで、呼び出し元との文字列の値が一緒かどうかを比較します。このコードの場合では、変数fooの文字列をequalsメソッドを使って変数barの文字列と同じ文字列なのかをチェックしています。

==演算子で比較する

通常、値を比較する方法として「==」が用いられることがありますが、文字列の比較に置いてはこの方法は使うべきではありません。その原因はJavaの仕組みにあります。次のコードを見てみましょう。

サンプルプログラム:

public class Main {

	public static void main(String[] args) {
		String foo = "Orange";
		String bar = new String("Orange");

		if (foo == bar) {
			System.out.println("fooとbarは一緒です。");
		} else {
			System.out.println("fooとbarは違います。");
		}
	}

}

実行結果:

fooとbarは違います。

あれ?おかしい?と思った方がいるかと思います。fooとbarは同じ値であるはずなのに「==」で比較しても違う文字列として扱われてしまいます。これはJavaの参照について解説する必要があります。

文字列は生成されるとメモリ上に文字列を保存しておくための場所(領域)が確保されます。そしてその確保した「場所」をfooやbarは保持しています。

つまり値を変数に保存しているわけではなく、場所を覚えておきfooやbarを使う際にその場所をたどって値を引っ張り出してくるという仕組みになっています。

この参照という仕組みがあるため「==」で比較した場合、文字列の値が一緒かどうかではなく文字列がメモリ上で格納されている場所が一緒かどうかという比較になります。そのため文字列の比較にはequalsメソッドを使うべきです。

では、続いて次のコードを見てみましょう。

サンプルプログラム:

public class Main {

	public static void main(String[] args) {
		String foo = "Orange";
		String bar = "Orange";

		if (foo == bar) {
			System.out.println("fooとbarは一緒です。");
		} else {
			System.out.println("fooとbarは違います。");
		}
	}

}

実行結果:

fooとbarは一緒です。

あれれ?今度は一緒と表示されました。先程は場所同士の比較を行っているため値の比較をしているわけではないと解説しました。

その解説が正しければ、今回も文字列は同じであっても変数fooと変数barそれぞれがメモリが確保された場所を変数に保存する仕組みであるため、別々の場所が保存されているはず!となるわけですがこの場合は少し違います。

何が違うのかというと、変数fooを「Orange」で初期化後、barも「Orange」で初期化する際に、Java側が機転を利かせて同じメモリの場所を指すようにする仕組みがあるのです。

つまり「==」で比較するときには同じ場所を参照(比較)しているため一緒という扱いになるのです。少しややこしいかもしれませんが、参照については別途理解しておく必要があるでしょう。

参照型であるStringの値を比較する時は「==」を使わず、equalsメソッドを使いましょう!それに対し、同じ文字でもプリミティブ型であるcharの値は「==」で比較します。それは、プリミティブ型は値そのものが変数に保存されているためです。

nullと比較する上での注意点

前項まではequalsメソッドを使いましょうと言ってきました。

しかしこのequalsメソッドにも使い方に注意が必要です。どの部分に注意すべきかというと次のコードを見てみましょう。

サンプルプログラム:

public class Main {

	public static void main(String[] args) {
		String foo = null;
		String bar = "bar";

		if (foo.equals(bar)) {
			System.out.println("fooとbarは一緒です。");
		} else {
			System.out.println("fooとbarは違います。");
		}
	}

}

これを実行するとNullPointer例外が発生して実行を停止していまいます。なぜこのようなことが起きるかは1行目を見ればすぐわかりますね。

変数fooにnullが入っており、そのnullが入った変数を無理やり使おうとしてequlasを呼び出していますが、fooの値はnullであるため、呼び出しに失敗して例外が発生しています。

メソッドを呼び出す際にはその変数がnullでないかをチェックしなければなりません。変数がnullがどうかをチェックするには「==」を使用します。

サンプルプログラム:

public class Main {

	public static void main(String[] args) {
		String foo = null;
		String bar = "bar";

		if (foo == null) {
			System.out.println("fooはnullです。");
		} else {
			if (foo.equals(bar)) {
				System.out.println("fooとbarは一緒です。");
			} else {
				System.out.println("fooとbarは違います。");
			}
		}
	}

}

実行結果:

fooはnullです。

「==」でnullかどうかをチェックし、nullでない場合に処理を行えばNullPointer例外が発生することはありません。

しかし、次のような書き方もあります。

サンプルプログラム:

public class Main {

	public static void main(String[] args) {
		String bar = null;

		if ("Orange".equals(bar)) {
			System.out.println("一緒です。");
		} else {
			System.out.println("違います。");
		}
	}

}

実行結果:

違います。

この書き方では「定数(Orange)」を先に持ってきてその後にequalsメソッドを呼んでいます。こうすることで定数がnullということはないのでNullPointer例外で動作しなくなる可能性を回避することができます。

Objects.equalsを使う

文字列を比較するのに、Objects.equalsメソッドを使うという手段もあります。Objectsクラスはjava.utilパッケージに属します。

サンプルプログラム:

import java.util.Objects;

public class Main {

	public static void main(String[] args) {
		String foo = null;
		String bar = "Orange";

		if (Objects.equals(foo, bar)) {
			System.out.println("一緒です。");
		} else {
			System.out.println("違います。");
		}
	}

}

実行結果:

違います。

このような形で使用します。これであればどちらかがnullだったとしてもNullPointer例外が発生することはありません。

しかしこの方法で両方の変数がnullだった場合、一緒の扱いとなるため文字列にnullが含まれることを良しとしない場合はnullチェックが必要でしょう。Objectsクラスのequalsメソッドについては、以下の記事でも詳しく解説しています!

【Java入門】Objectsクラスのequalsメソッドでnullを安全に比較
更新日 : 2018年11月20日

equalsメソッドで比較をする方法総まとめ

equalsメソッドで比較する方法については、以下の記事でも詳しく解説しています!

まとめ

いかがでしょうか。文字列の比較にはStringクラスのequalsメソッドかObjects.equalsメソッドを使いましょう。また比較の際には文字列がnullであることを考慮しておかなければなりません。

文字列の比較について忘れてしまった場合はぜひこの記事を思い出して下さい。

LINEで送る
Pocket

無料でSEからWebエンジニアへ転職しませんか?



侍エンジニア塾では、完全未経験の方から現在SEだけどプログラミングはやっていないという経験者まで、幅広い方々の人生を好転させるプログラミング指導を行ってきました。SEの方とお話していくなかで、

  • システムエンジニアという職業だけどコードが書けない
  • 事務作業が多くスキルがないため将来が不安
  • スクールに通うと完全未経験者と同じスタートになるからレベルが合わない
という、すでに知識があるSEならではのお悩みがあることに気づきました。そんな方におすすめなのが、弊社の「転職コース 」です。

弊社では、マンツーマンでレッスンを行いますので、現在お持ちの知識レベルからカリキュラムを作成いたします。さらにこちらの転職コースは無料で受講を始められて転職成功でそのまま卒業できるというとてもお得なコースとなっています。

既に知識のあるSEといっても転職は年齢が若いほど受かりやすいため、まずは無料体験レッスンで今の現状や理想の働き方について一緒に考えていきましょう。

まずは無料体験レッスンを予約する

書いた人

オータケ

オータケ

30歳、フリーランスプログラマ。中学の頃よりプログラミングに興味を持ちゲーム開発やWebサイト構築などを経験
新しいフレームワークやライブラリに興味があり革新的な機能が含まれていると泣いて喜ぶ。

おすすめコンテンツ

あなたにぴったりなプログラミング学習プランを無料で診断!

プログラミング学習の効率を劇的に上げる学習メソッドを解説