【Java入門 実用編】文字列の基本的な操作(2) | 空白/同一/開始/終了の判定・置換・大小変換
2025.07.18
前回の記事(文字列の基本的な操作(1))では、文字列の結合、分割、切り出しおよび、部分的に文字列を含む場合の確認についてご紹介しました。当記事では、文字列の各種判定や置換、大文字と小文字の変換などの機能について、具体的なコード例とあわせてご紹介します。
はじめに(前提条件)
当記事内の記述については、以下の前提条件とします。
・当記事内で「文字列」と記述されている場合、特に注記がなければ Java の String クラスのインスタンスを指すものとします。
・当記事内でクラスを指定せずにメソッド名が記述されている場合も、String クラスのメソッドを指すものとします。
文字列がnull・空白かどうかを判定する
null の判定
文字列(String)についても他のクラス同様に、変数が null であるかどうかは比較演算子「==」(または「!=」)で判定することができます。
String str = null;
// null であることをチェック
if(str == null) {
System.out.println("strはnullです");
}
// null ではないことをチェック
if(str != null) {
System.out.println("strはnullではありません");
}
String クラスのインスタンスメソッドを利用する場合は、null ではないことが明白である場合を除き、先に null ではないことを確認する必要があります。
isEmpty メソッド(空文字の判定)
isEmpty メソッドは、文字列が空文字(長さ0の文字列)であるかどうかを判定します。インスタンスメソッドのため、変数が null の場合は実行できません。(実行時に NullPointerException が発生します)
isEmpty メソッド - Java 21 APIドキュメント
String str1 = "";
String str2 = "ABC";
// true(空文字)
System.out.println(str1.isEmpty());
// false("ABC")
System.out.println(str2.isEmpty());
isBlank メソッド(空白の判定 ※Java11以降)
isBlank メソッドでは、文字列が空、または半角・全角スペースや改行コード(\r , \n)、タブ(\t)などの空白文字(whitespaceコード・ポイント)のみで構成されているかどうかを判定します。
isBlank メソッド - Java 21 APIドキュメント
String str1 = "";
String str2 = " ";
String str3 = "\t";
String str4 = "\r\n";
// 以下は全てtrue
// 空文字
System.out.println(str1.isBlank());
// 半角スペース+全角スペース
System.out.println(str2.isBlank());
// タブ(\t)
System.out.println(str3.isBlank());
// 改行コード(\r\n)
System.out.println(str4.isBlank());
文字列内の文字が空白文字であるかどうかは、Character クラスの isWhitespace メソッドによって判定されます。
文字列の内容が同一かどうかを判定する
equals メソッド(一致判定)
equals メソッドは、文字列の内容が引数の値と同一かどうかを判定することができます。文字列インスタンスの変数同士を「==」演算子で比較した場合、「参照しているインスタンスが同一かどうか」が比較されるため、文字列の値同士を比較する場合は equals メソッドを利用する必要があります。
equals メソッド - Java 21 APIドキュメント
// 別のインスタンスを参照するよう new キーワードを利用
String str1 = new String("abc");
String str2 = new String("abc");
// false(別のStringインスタンス)
System.out.println( str1 == str2 );
// true(文字列としての値が同一)
System.out.println( str1.equals(str2));
※ == 演算子での比較について(文字列のインスタンスと文字列プールについて)
文字列(String)の変数に対し、文字列リテラル("abc" など)を値に指定した場合、文字列プールと呼ばれる領域に同一内容のインスタンスがあれば、そのインスタンスへの参照を変数に対して設定します。
このため、以下のコードでは、「==」演算子で比較した際も true が返されることに注意してください。
// 同一内容の文字列リテラルを値に設定
String str1 = "abc";
String str2 = "abc";
// true(同一のStringインスタンスを参照している)
System.out.println( str1 == str2 );
※文字列プールの詳細については、過去の記事(Java入門 第10回 Javaの演算子 2.3.2 参照型変数の比較と特殊な例について)をご参照ください。
equals はインスタンスメソッドですので、比較元の変数が null の場合は利用できません。このため、null の可能性がある変数の場合は null チェックを先に実行してから equals メソッドを利用する必要があります。引数に渡す文字列の変数は null であっても問題ありません。
if ( str1 != null && str1.equals(str2) ){
System.out.println("str1 と str2 の文字列は同一です。");
}
実際のアプリケーション開発では、ライブラリや共通部品などを準備して null チェック付のメソッドを利用することが多いと思います。
下記のサンプルコードは、共通部品化されたメソッドの例です。(あくまで例ですので、どちらも null の場合の動作などは、作成するメソッドの目的にあわせて決定されることに注意してください)
public static boolean isEqual(String s1, String s2){
if(s1 == null){
// どちらもnullの場合はtrue
if(s2 == null){
return true;
}
return false;
}
return s1.equals(s2);
}
また equals メソッドは Object クラスのオーバーライドメソッドであるため、引数の型が Object 型ですが、引数が文字列以外であった場合は常に false が返される(自動的に toString で文字列として比較はされない)ことに注意してください。
equalsIgnoreCase メソッド(大文字小文字を無視)
equalsIgnoreCase メソッドは、equals メソッド同様に文字列の内容が同一かどうかを判定しますが、判定の際に大文字・小文字を区別せずに比較します。
equalsIgnoreCase メソッド - Java 21 APIドキュメント
equalsIgnoreCase メソッドでは、アルファベットのように大文字と小文字が存在する文字についてのみ、その区別を無視して判定されます。全角文字と半角文字(例:"ABC" と "ABC")については、通常通り別の文字として区別して判定されます。
String str1 = "abc";
String str2 = "aBc";
String str3 = "AbC";
String str4 = "ABC";
// 以下は全てtrue(equals メソッドの場合は全て false)
System.out.println(str1.equalsIgnoreCase(str2));
System.out.println(str1.equalsIgnoreCase(str3));
System.out.println(str1.equalsIgnoreCase(str4));
System.out.println(str2.equalsIgnoreCase(str3));
System.out.println(str2.equalsIgnoreCase(str4));
System.out.println(str3.equalsIgnoreCase(str4));
// false(全角(ABC)/半角(ABC)は別の文字として判定)
String str5 = "ABC";
System.out.println(str4.equalsIgnoreCase(str5));
contentEquals メソッド(CharSequence との一致判定)
contentEquals メソッドでは、文字列と CharSequence が同じ内容であるかを判定します。引数の型が CharSequence インターフェイスのため、String 型以外にも StringBuilder などの CharSequence インターフェイスの実装クラスであれば、そのまま文字列と比較することが可能です。
contentEquals メソッド - Java 21 APIドキュメント
ただし、contentEquals メソッドでは引数に null を渡した場合、NullPointerException が発生するため注意してください。
String str1 = "";
String str2 = "ABC";
StringBuilder sb = new StringBuilder();
// true(空文字と空のStringBuilderインスタンスを比較)
System.out.println(str1.contentEquals(sb));
// true(文字列"ABC"と、内容が"ABC"のStringBuilderインスタンスを比較)
sb.append("ABC");
System.out.println(str2.contentEquals(sb));
実際のアプリケーション開発では、StringBuilder などのオブジェクトを比較する際に toString メソッドを利用して String 型に変換してから equals メソッドで比較することも多いため、contentEquals メソッドを使う機会は少ないかもしれません。
しかし、toString メソッドを呼び出すと新しい String オブジェクトが生成されます。そのため、大量のデータをループ処理で扱うなど、メモリ使用量や処理性能を重視する場合には、新しいオブジェクトを生成せずに比較できる contentEquals メソッドの利用を検討すると良いでしょう。
文字列の先頭/末尾が合致するかを判定する
startsWith メソッド(先頭の一致を判定)
startsWith メソッドは、文字列が「引数で指定した文字列」で開始しているかどうかを判定します。
startsWith メソッド - Java 21 APIドキュメント
String str = "ABCDEFG";
String prefix1 = "ABC";
String prefix2 = "CDE";
// true(先頭が「ABC」で始まっているかどうか)
System.out.println(str.startsWith(prefix1));
// false(先頭が「CDE」で始まっているかどうか)
System.out.println(str.startsWith(prefix2));
startsWith メソッドは、第2引数に一致判定を行う開始位置(0から始まるインデックス値)を指定することも可能です。0より大きい値を指定した場合は、文字列の先頭ではなく指定したインデックスの位置からの文字列が、指定した文字列で開始しているかどうかを判定します。
String str = "ABCDEFG";
String prefix1 = "ABC";
String prefix2 = "CDE";
// false(2文字目より後ろの文字列(CDEFG)が「ABC」で始まっているかどうか)
System.out.println(str.startsWith(prefix1, 2));
// true(2文字目より後ろの文字列(CDEFG)が「CDE」で始まっているかどうか)
System.out.println(str.startsWith(prefix2, 2));
インデックス値に負の値や文字列の長さを超える値を指定した場合は、エラーとはならずに常に false が返されます。
endsWith メソッド(末尾の一致を判定)
endsWith メソッドは、文字列の末尾が引数で指定した文字列で終了しているかどうかを判定します。startsWith メソッドとは異なり、インデックス値は指定できず、常に文字列の末尾を判定します。
endsWith メソッド - Java 21 APIドキュメント
String str = "ABCDEFG";
// true(文字列が「G」で終わっているかどうか)
System.out.println(str.endsWith("G"));
// true(文字列が「EFG」で終わっているかどうか)
System.out.println(str.endsWith("EFG"));
// true(文字列が「ABCDEFG」で終わっているかどうか)
System.out.println(str.endsWith("ABCDEFG"));
// false(文字列が「CDE」で終わっているかどうか)
System.out.println(str.endsWith("CDE"));
文字列の置換
replace メソッド(文字または文字列の一致する箇所を全て置換)
replace メソッドは、文字列内の指定した文字または文字列を、別の文字・文字列に置き換えることができます。
文字を指定する場合は置換対象の char と置換する char を指定し、文字列を指定する場合は、String を含む CharSequence の実装クラスを指定することができます。replace メソッドは指定した内容で置換した結果の文字列を返却しますが、置換元の文字列は変更されないことに注意してください。
replace メソッド - Java 21 APIドキュメント
String str = "abcabcabc";
StringBuilder sbOrg = new StringBuilder("ab");
StringBuilder sbRep = new StringBuilder("XYZ");
// 文字(char)で変換
// 「xbcxbcxbc」と出力(文字(char)'a' を指定して文字 'x' に置換)
System.out.println(str.replace('a', 'x'));
// 文字列(String)で変換
// 「azazaz」と出力(文字列(String)"bc" を指定して文字列 "z" に置換)
System.out.println(str.replace("bc", "z"));
// String 以外の CharSequence でも置換が可能
// 「XYZcXYZcXYZc」と出力(StringBuilder("ab") を指定して文字列 StringBuilder("XYZ") に置換)
System.out.println(str.replace(sbOrg, sbRep));
文字列で置換を行う場合は、置換前の文字数と置換後の文字数が一致する必要はありません。このため、置換先の文字列に空文字("")を指定することで、特定の文字列を除去することも可能です。
replaceFirst メソッド(正規表現に最初に合致した箇所を置換)
replaceFirst メソッドでは、文字列に対して指定した「正規表現」に合致する箇所のうち、最初の1か所を指定した別の文字列に置き換えることができます。
前回の記事で紹介した split メソッド の区切り文字と同様に、置換対象として正規表現を指定することに注意してください。
replaceFirst メソッド - Java 21 APIドキュメント
String str = "abcabcabc";
String strCredit = "0123-4567-8901-2345";
// 「XYZabcabc」と出力(「abc」に最初に合致する箇所を「XYZ」に変換
System.out.println(str.replaceFirst("abc", "XYZ"));
// 「\d+(数字1つ以上の連続 を示す正規表現)」に最初に合致する箇所を、先頭から3回「****」に変換)
String strMask = strCredit.replaceFirst("\\d+", "****")
.replaceFirst("\\d+", "****")
.replaceFirst("\\d+", "****");
// 「****-****-****-2345」と出力
System.out.println(strMask);
replaceFirst メソッドも replace メソッド同様、置換した結果の文字列を返却し、置換元の文字列は変更されません。
replaceAll メソッド(正規表現に合致した箇所を全て置換)
replaceAll メソッドでは、文字列に対して指定した「正規表現」に合致する箇所を全て別の文字列に置き換えることができます。
replaceAll メソッド - Java 21 APIドキュメント
String strYmd = "2025年01月23日";
// 「****年**月**日」と出力(全ての数字1文字(正規表現:\d )を「*」に置換)
System.out.println(strYmd.replaceAll("\\d", "*"));
// 「2025/01/23」と出力(「年」または「月」に合致する文字を「/」に、「日」を空文字に置換)
System.out.println(strYmd.replaceAll("[年月]", "/").replace("日", ""));
replaceAll メソッドも replace メソッドや replaceFirst メソッドと同様に、置換した結果の文字列を返却し、置換元の文字列は変更されません。
大文字⇔小文字の変換
toUpperCase メソッド(大文字に変換)
文字列を大文字の文字列に変換するには、toUpperCase メソッドを利用します。
toUpperCase メソッド - Java 21 APIドキュメント
toUpperCase メソッドでは、漢字やかな文字など、大文字/小文字の区別がない文字は元の文字のまま保持されます。また、大文字/小文字の区別がある文字とない文字が混在する文字列では、区別のある文字のみ大文字に変換されます。
また、メソッドの戻り値(変換後の文字列)は新しい文字列として返され、メソッドを呼び出した変数の値自体は変更されないことに注意してください。
String str1 = "abcdefg";
String str2 = "8月は英語で「August」です。";
String str3 = "トウキョウトッキョキョカキョク";
// 「ABCDEFG」と出力(全て大文字に変換)
System.out.println(str1.toUpperCase());
// 「8月は英語で「AUGUST」です。」と出力(大文字に変換できない文字が混在する場合は、変換できる文字のみ変換)
System.out.println(str2.toUpperCase());
// 「トウキョウトッキョキョカキョク」と出力(半角文字や日本語の拗音・促音は変換されない)
System.out.println(str3.toUpperCase());
toUpperCase メソッドでは、引数に Locale を指定することも可能です。(Locale を指定しない場合はデフォルト・ロケールが使用されます)
ただし、Java 21 現在ではトルコ語のアルファベット以外は同じ動作となっているため、ほとんどのケースでは引数なし(デフォルト・ロケールを使用)として問題ないでしょう。
toLowerCase メソッド(小文字に変換)
toUpperCase とは逆に、文字列を小文字に変換するには toLowerCase メソッドを利用します。
toLowerCaseメソッド - Java 21 APIドキュメント
toUpperCase メソッドと同様、変換の対象になるのは大文字/小文字の区別がある文字のみとなり、変換結果として新しい文字列が返されます。こちらもメソッドを呼び出した変数の値自体は変更されないため注意が必要です。
String str1 = "ABCDEFG";
String str2 = "8月は英語で「August」です。";
// 「ABCDEFG」と出力(全て小文字に変換)
System.out.println(str1.toLowerCase());
// 「8月は英語で「august」です。」と出力(小文字に変換できない文字が混在する場合は、変換できる文字のみ変換)
System.out.println(str2.toLowerCase());
toUpperCase メソッド同様に、toLowerCase メソッドでも引数にロケールを指定することが可能ですが、こちらもほとんどのケースでは指定なし(デフォルト・ロケールの使用)として問題ないでしょう。