検索

キーワード


【Java】文字列 - String クラスの使い方(比較、判定、検索)

  • 公開日:2020-08-28 14:28:17
  • 最終更新日:2020-12-26 23:47:26
【Java】文字列 - String クラスの使い方(比較、判定、検索)

こんにちは。新人エンジニアのサトウです。

システムエンジニアとして駆け出したばかりですが、

初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。


プログラム初心者にも、プログラムに興味がある人も、

短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!


String クラスとは

Stringクラスはjava.langパッケージに含まれているJavaプログラミングにおける必須的なクラスで、文字列を表現します。

最初からパッケージごとimportされているので、import宣言しなくても使うことができます。

また他のクラスと同様に様々なメソッドが実装されており、それらを使用して文字列を操作することができます。


※Stringクラスについては他の記事でも取り扱っています。

(文字列の連結・切り出し・長さの表示・分割・変換・置換・空白除去などの基本操作)

関連記事:

【Java】Stringクラスの理解と基本的な文字列操作

【Java】StringBufferクラスとStringBuilderクラスの文字列操作

【Java】MessageFormatクラスでの文字列置換

【Java】Stringクラスformatメソッドの文字列整形とエスケープシーケンス

【Java】Java8 以降に追加された文字列結合(StringクラスjoinメソッドとStringjonerクラス)

【Java】"サロゲートペア"を包含する文字列の操作

【Java】文字列・正規表現


今回はStringクラスに実装されているメソッドを使って、文字列の比較・判定・検索の操作を紹介します。




文字列の比較

指定された文字列と比較して結果を返します。返す結果はboolean値やint値など、メソッドによって異なります。

2つの文字列を比較した違いによって処理を分けたい時などに使用されます。


文字列比較の注意点! "== 演算子" が不適切なワケ

Java で値を比較するのに真っ先に思いつくのが ==(イコールズ演算子)です。

== 演算子は同じ値であるかを確認するための演算子です。

基本型(プリミティブ型)では、値が等しければ同じものであるので問題ありません。

しかし、参照型では同じ値であっても等しいと判断されないことがあります。


まずは、同じ実装を書いても参照型(Integer)と基本型(int)の値では比較結果が異なることを確認しましょう。


◆実装例1

public class Test {
	public static void main(String[] args) {
		//参照型(String型)の==演算子
		Integer a = 12345;
		Integer b = 12345;

		System.out.println(a == b);

		//基本型の==演算子
		int d = 12345;
		int c = 12345;

		System.out.println(c == d);

	}
}

◆出力結果

false
true


変数に格納されている値は同じでも==演算子を使用した比較結果が異なるのは、

参照型の値はプログラム内部の処理で異なる場所に格納されることがあるからです。

参照型は値ではなく参照先(ポインタ)を保持しています。

インスタンス化されるたびに新しい参照先が生成されるため、同じ値を持った同じ型のオブジェクトでも、インスタンス(参照先)が異なっていれば比較結果は等しいと判断されません。

==演算子を使った場合は、値ではなく参照先(ポインタ)同士を比較してしまいます。


一方で基本型は値そのものを保持しています。

==演算子を使用した場合に、変数の値そのものを比較することができます。


参照先を比較しているのがわかる例を確認しましょう。

◆実装例2

public class Test {
	public static void main(String[] args) {
		//比較される値
		String s = "比較";

		//比較する値1
		String t = "比較";
		System.out.println(s == t);

		//比較する値2
		String u1 = "比";
		String u2 = "較";
		String u = u1 + u2;
		System.out.println(s == u);
	}
}

◆出力結果

true
false

この結果からString値でも値そのものではなく、参照先(ポインタ)同士を比較していることがわかったでしょうか。

変数sと変数tは今回同じ参照先を保持しているので、==演算子の結果はtrueになっています。

しかし、同じ値が格納されているはずの変数uは違う参照先を保持しているので、

値sとの結果はfalseになってしまいます。

==演算子を参照型の値で使用すると、こうしたように値そのものを比較してくれないので注意しましょう。

Java で String 値(文字列)を比較したい場合は、String クラスに実装されているメソッドを使うようにしましょう。


equals メソッド (文字列が等しいか比較する)

boolean	equals(Object anObject)

オブジェクトが同一なのかを調べるのではなく、格納されている文字列が等しいかどうかを

調べるのにはStringクラスで実装されているequalsメソッドを使います。

比較対象にnullが代入されている場合は例外が発生してしまうので注意しましょう。

public class Test {
	public static void main(String[] args) {
		String s="比較";
		String s1="比";
		String s2="較";
		String s3=s1+s2;
		
		System.out.println(s.equals(s3));
	}
}

出力結果

true


(補足)Objects.equals メソッド

Stringクラスのequalsメソッドではnullが代入されている場合(対象文字列の変数が null の場合)に例外が発生してしまいます。

nullでも例外が発生しないようにするにはObjectsクラスのequalsメソッドを使うことで可能になります。

static boolean	equals(Object a, Object b)

引数が相互に等しい場合はtrueを返し、それ以外の場合はfalseを返します。



Objectsクラスはjava.utilパッケージに含まれており、Java7から使用可能になりました。

使用する際は Objects クラスをインポートする必要があります。

equalsメソッドはstatic メソッドなので、Objects クラスのインスタンスを生成することなく使用することができます。

import java.util.Objects;

public class Test {
	public static void main(String[] args) {
		String s ="比較";
		String n = null;

		//Objectsクラスequalsメソッド
		System.out.println(Objects.equals(s,n));

		//Stringクラスequalsメソッド
		System.out.println(n.equals(s));
	}
}

出力結果

false
Exception in thread "main" java.lang.NullPointerException


equalsIgnoreCase メソッド (大文字小文字を区別せずに比較する)

boolean	equalsIgnoreCase(String anotherString)

equalsメソッドの機能に加え大文字と小文字を区別せずに比較したい時は、

equalsIgnoreCaseメソッドを使いましょう。

public class Test {
	public static void main(String[] args) {
		String s="HIKAKU";
		String s1="hikaku";

		//equalsメソッド
		System.out.println(s.equals(s1));
		//equalsIgnoreCaseメソッド
		System.out.println(s.equalsIgnoreCase(s1));
	}
}

出力結果

false
true


regionMatches メソッド (範囲を指定して比較する)

boolean	regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len) 

※【オプション】boolean ignoreCase (省略すると、デフォルトで大文字小文字が区別されます。)

このメソッドは、文字列範囲を限定して比較することができます。

部分的な文字列だけを比較したい際にこのメソッドを使用します。


引数に様々な要素を指定していますので確認しましょう。

regionMatchesメソッドの引数

引数が以下の関係の場合は結果がfalseになるので注意してください。


toffsetが負の場合。

ooffsetが負の場合。

toffset+lenが比較文字列の長さより大きい場合。

ooffset+lenが引数otherの長さより大きい場合。


public class Test {
	public static void main(String[] args) {
		String s = "MOZIRETUnoHIKAKU";
		String s1 = "hikaku";

		System.out.println(s.regionMatches(true, 10, s1, 0, 6));
		System.out.println(s.regionMatches(false, 10, s1, 0, 6));
		System.out.println(s.regionMatches(10, s1, 0, 6));
	}
}

出力結果

true
false
false


compareTo メソッド (大小比較する)

int	compareTo(String anotherString)

compareToメソッドの利用で、値の大小比較を行うことが可能になります。

日付などの大小比較も行うことができるので、ソート処理など様々な場面で利用されているメソッドです。


このメソッドは、二つの値を辞書的に比較してint型で結果を返します。

ここでいう「辞書的に比較する」とは、辞書の語順で大小比較をすることを指しています。

比較対象が引数よりも辞書的に先にあればマイナス値、後にあればプラス値、等しければ ゼロ(0)を結果として出します。


比較は文字列内のそれぞれの文字のUnicode値に基づいて辞書的に行われます。

Unicodeとは
文字コードの国際標準の一つ
世界中の様々な言語の文字を収録して通し番号を割り当て同じコード体系のもとで使用できるようにしたもの。


public class Test {
	public static void main(String[] args) {
		String c="a";
		String c1="b";
		String s="HIKAKU";
		String s1="hikaku";

		System.out.println(c.compareTo(c1));
		System.out.println(c1.compareTo(c));
		System.out.println(s.compareTo(s1));
	}
}

出力結果

-1
1
-32


compareToIgnoreCase メソッド (大文字小文字を区別せずに大小比較する)

int	compareToIgnoreCase(String str)

compareToメソッドの機能に加えて、大文字と小文字を区別せずに比較したい時に使用します。

public class Test {
	public static void main(String[] args) {
		String s="HIKAKU";
		String s1="hikaku";

		System.out.println(s.compareToIgnoreCase(s1));
		System.out.println(s.compareTo(s1));
	}
}

出力結果

0
-32

startsWith / endsWith メソッド (開始文字列、終端文字列を比較する)

boolean	startsWith(String prefix, int toffset)

※【オプション】int toffset

startWithメソッドは比較文字列が指定された接頭辞(prefix)で始まるかどうかを判定します。

第二引数を指定した場合は、指定されたインデックスから比較判断を開始します。

boolean	endsWith(String suffix)

endWithメソッドは比較文字列が指定された接尾辞(suffix)で終るかどうかを判定します。

それぞれbooleanで結果を返します。大文字/小文字を区別します。

public class Test {
	public static void main(String[] args) {
		String url="https://works.forward-soft.co.jp/blog";

		System.out.println(url.startsWith("https://"));
		System.out.println(url.startsWith("works",8));
		System.out.println(url.endsWith("blog"));
		System.out.println(url.startsWith("HTTPS://"));
	}
}

出力結果

true
true
true
false


matches メソッド (パターンと一致するか判定する)

boolean	matches(String regex)

比較文字列が、指定された正規表現(regular expression=regex)と一致するかどうかを判定します。


例で使用している正規表現は「hikaku」あるいは「Hikaku」の文字列を表しています。

"[hH]ikaku"           ※[ab]➡「a」or「b」という正規表現


正規表現について詳しくは以下のリンクを参考にしてください。

参考:javadoc-Pattern(正規表現) 

   【Java】文字列・正規表現

public class Test {
	public static void main(String[] args) {
		String s  ="hikaku";
		String s1 ="Hikaku";
		String s2 ="mikaku";

		System.out.println(s.matches("[Hh]ikaku"));
		System.out.println(s1.matches("[Hh]ikaku"));
		System.out.println(s2.matches("[Hh]ikaku"));
	}
}

出力結果

true
true
false





文字列の判定

変数に格納されている値が空をどうかを条件にして処理を分けたい時に使用できる判断メソッドを紹介します。

Java プログラミングにおいては、「空の値」の概念がいくつか存在します。

以下を確認してしっかり区別しましょう。



◆空文字 プログラミングにおいて空文字とは、長さが0の文字列のことを指します。

String empty ="";

◆空白文字 スペースキーを押すと表示される、何も書かれていない文字のことを指します。

「a」「b」のように一つの文字として扱われます。スペースとも呼ばれ、半角/全角スペースも空白文字です。

String blank =" ";

◆NULL 値もなければ要素の定義もされていない状態のことを指します。


今回は空文字と空白文字の判断を紹介します。


equalsメソッド (文字列が等しいか比較する)

boolean	equals(Object anObject)

引数に空白文字あるいは空文字を指定し、結果がtrueであれば空白文字/空文字であるかを判定することができます。

しかし、比較対象と引数が文字数まですべて一致していないとtrueにならないので注意しましょう。

public class Test {
	public static void main(String[] args) {
		//空白文字
		String b =" ";
		//空文字
		String e ="";

		System.out.println(" ".equals(b));
		System.out.println("".equals(e));
		System.out.println("     ".equals(b));
	}
}

出力結果

true
true
false


isEmpty メソッド (空文字か判定する)

boolean	isEmpty()

isEmptyメソッドは文字列の長さが0であればtrueを返すので、結果がtrueであれば空文字と判定できます。

このメソッドは、次に紹介するlengthメソッドを内部的に呼び出しています。

public class Test {
	public static void main(String[] args) {
		//空白文字
		String b =" ";
		//空文字
		String e ="";
		//null
		String n =null;

		System.out.println(b.isEmpty());
		System.out.println(e.isEmpty());
		System.out.println(n.isEmpty());
	}
}

出力結果

false
true
Exception in thread "main" java.lang.NullPointerException


length メソッド (文字列の長さを取得する)

int	length()

lengthメソッドは文字列の長さをintで結果を返すので、戻り値が0であれば空文字と判定できます。

また、文字列に空白のみがある場合、空白文字の文字数を確認できます。

public class Test {
	public static void main(String[] args) {
		//空白文字
		String b =" ";
		//空文字
		String e ="";
		//null
		String n =null;

		System.out.println(b.length());
		System.out.println(e.length());
		System.out.println(n.length());
	}
}

出力結果

1
0
Exception in thread "main" java.lang.NullPointerException




文字列の検索

文字列内から部分文字列や文字を探したい際に使用するメソッドを紹介します。

indexOf メソッド (指定文字列の位置を検索する)

int indexOf(int ch, int fromIndex)
int indexOf(String str, int fromIndex)

※【オプション】int fromIndex

指定された文字・部分文字列がこの文字列内で最初に出現する位置のインデックスを返します。

第二引数に【fromIndex】を指定した場合は、指定されたインデックス以降の文字列を対象にします。

検索対象が見つからない場合は「-1」を返します。

public class Test {
	public static void main(String[] args) {
		String s ="HIKAKU";

		System.out.println(s.indexOf("K"));
		System.out.println(s.indexOf("k"));
	}
}

出力結果

2
-1


lastIndexOf メソッド (指定文字列が最後に登場する位置を検索する)

int lastIndexOf(int ch, int fromIndex)
int lastIndexOf(String str, int fromIndex)

※【オプション】int fromIndex

指定された文字・部分文字列が最後に出現する位置のインデックスを返します。

第二引数に【fromIndex】を指定した場合、検索は指定されたインデックスから開始され先頭方向に検索が行われます。

検索対象が見つからない場合は「-1」を返します。

public class Test {
	public static void main(String[] args) {
		String s ="HIKAKU";

		System.out.println(s.lastIndexOf("K"));
		System.out.println(s.lastIndexOf("k"));
	}
}

出力結果

4
-1


contains メソッド (指定文字列が含まれるかを判定する)

boolean contains(CharSequence s)

引数に指定された文字が文字列内に含まれている場合に「true」を返します。

検索対象が見つからない場合は「false」を返します。

public class Test {
	public static void main(String[] args) {
		String s ="HIKAKU";

		System.out.println(s.contains("K"));
		System.out.println(s.contains("k"));
	}
}

出力結果

true
false


charAt メソッド (指定位置の文字を取得する)

char	charAt(int index)

文字一つの検索はcharAtメソッドを使うことができます(文字列ではなく、文字であることに注意)。

指定されたインデックスの文字(char値)を結果として返します。

public class Test {
	public static void main(String[] args) {
		String s ="HIKAKU";

		System.out.println(s.charAt(5));
	}
}

出力結果

U



【著者】

新人SE・サトウ

読者を始め私自身も知りたい!と思うような知って得するプログラミング知識やIT情報を日々発信中です。
筆者の憧れの人物は、コリン・ファースさん、渡部篤郎さん。
教養のあるカッコいい大人になれるよう、プログラミングを始め興味関心を持ったことを毎日勉強しております !!

よく読まれている記事
【Java】JSPでタグライブラリを使う(JSTL)

【Java】JSPでタグライブラリを使う(JSTL)

こんにちは。エンジニアの新田です!ここでは、システムエンジニアとして働いている私が、システム開発手法や開発言語について紹介していこうと思います。今回は、JSPの標準タグライブラリ「JSTL」について紹介します。Javaについて勉強している方、Webアプリケーションを構築したいと思っている方の参考になれば幸いです!関連記事リンク: 【Java】JSPの基本的な構文/【Java】JSPのアクションタグ

【Java】Stringクラス文字列を操作するメソッドの使い方まとめ!実例も紹介!

【Java】Stringクラス文字列を操作するメソッドの使い方まとめ!実例も紹介!

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者✅にも、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!そもそもStringとは何?『 String 』... Java言語において文字列のデータ型を指します。基本デ

【Java】文字列の置き換え(String#format)!エスケープシーケンスのまとめも!!

【Java】文字列の置き換え(String#format)!エスケープシーケンスのまとめも!!

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者✅にも、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!Stringクラスformatメソッドの文字列整形【java.utilパッケージ】Formatterクラスfo

【Java】文字列格納後に変更可能!?StringBufferクラスとStringBuilderクラス!

【Java】文字列格納後に変更可能!?StringBufferクラスとStringBuilderクラス!

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者にも✅、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!文字列を扱う3つのクラス【java.langパッケージ】java.langパッケージの文字列を扱うクラスにはS

【Java】値?変数?型??しっかり解説!『データ型(プリミティブ型と参照型)』

【Java】値?変数?型??しっかり解説!『データ型(プリミティブ型と参照型)』

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者✅にも、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!プリミティブ型と参照型プログラム開発では型を持った変数を使ってデータのやり取りをしますが、データ型によって仕様