Menu

Javaの文字列(String):生成、連結、Stringメソッドの使い方

Javaの文字列の仕組み:生成、+での連結、なぜイミュータブル(変更不可)なのか、equalsでの比較、そしてlength・substring・replaceといった日常的なStringメソッド。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

文字列(String)とは

String は文字の並びを保持します。名前、文章、ファイルから読み込んだ1行などのテキストです。前のページでは参照型の一覧の中に String が挙げられているのを見ましたが、ここでは実際に文字列を扱っていきます。文字列リテラルはダブルクォートで書きます(シングルクォートは単一の char 用に予約されています):

name.length() は文字数を返します。"Ada" なら 3 です。これはメソッド呼び出しなので、括弧が必要です。

文字列を連結する

+ 演算子は文字列どうしをつなぎ合わせます。+ のどちらか一方が文字列なら、もう一方は自動的にテキストへ変換されるため、数値やブール値を余計な手間なく混ぜることができます:

一つ落とし穴があります。+ は左から右へ評価されるため、"" + 1 + 2"12" になります(文字列 + int、続いて文字列 + int)が、1 + 2 + """3" になります(2つの整数が先に足され、その後でテキストになる)。迷ったら、計算部分を括弧で囲みましょう。

文字列はイミュータブル(変更不可)

これはJavaの文字列について理解すべき最も重要なことです。String は生成された後、決して変化しません。文字列を「変更する」ように見えるすべてのメソッドは、実際にはまったく新しい文字列を返し、元のものはそのまま残します。したがって、戻り値を受け取り忘れると、何も起こりません:

最初の呼び出しは "HELLO" を計算してすぐに捨てます。目に見える効果があるのは、s に代入し直す2行目だけです。これはほとんどの人が一度ははまる落とし穴です。

文字列を比較する

2つの文字列の内容を比較するには .equals() を使います。== に手を伸ばすのは初心者の典型的なミスです。== は「これらはメモリ上で同じオブジェクトか?」を尋ねるのであって、「同じテキストを持っているか?」ではありません:

ここで a == bfalse になるのは、new String(...) が別のオブジェクトを強制的に作るからです。文字列の値は常に .equals()(大文字・小文字を無視する場合は .equalsIgnoreCase())で比較しましょう。片方が null になりうるときにクラッシュを避ける便利なテクニックは、リテラル側で .equals を呼ぶことです。"yes".equals(input) は、たとえ inputnull でも例外を投げません。

日常的なStringメソッド

文字列はイミュータブルなので、これらのメソッドはどれも元のものを変更するのではなく、新しい文字列(または値)を返します。次に挙げるのは、いつも使うことになるものです:

メソッドチェーンに注目してください。s.trim().toUpperCase() が動くのは、trim() が文字列を返し、その文字列に対して toUpperCase() を呼べるからです。substring ももう一つの定番です。開始インデックス(含む)と、省略可能な終了インデックス(含まない)を取ります:

インデックスは0始まりなので、substring(0, 4) は0番目から3番目までの文字を取り出します。末尾を超えるインデックスを要求すると StringIndexOutOfBoundsException が投げられます。

ループの中で文字列を組み立てる

いくつかの断片をつなぐだけなら + での連結で問題ありませんが、大きなループの中でそれをやると遅くなります。+ のたびに新しい文字列が作られ、すべてがコピーされるからです。ループの中でテキストを組み立てるときは、バッファをその場で変更し、最後に一度だけ最終的な文字列を生成する StringBuilder を使いましょう:

append は同じビルダーを返すので、呼び出しをチェーンできます。最後に .toString() を呼び出すと、通常の String が得られます。一度きりの結合なら + のままでよいですが、多くの断片を積み重ねるなら StringBuilder が適切なツールです。

次へ:文字列のフォーマット

桁をそろえた列、固定の小数点以下桁数、ゼロ埋めした数値が必要になると、連結はすぐにごちゃごちゃになります。Javaの String.formatprintf% プレースホルダーを使ったテンプレートで、それらすべてをきれいに処理します。それが次のページのテーマです。

よくある質問

Javaで2つの文字列を比較するにはどうすればいいですか?

内容を比較するには .equals() を使います。a.equals(b) は文字が一致すると true を返します。文字列の値を比較するのに == を使ってはいけません== はオブジェクトの参照を比較するため、同じテキストを持つ2つの文字列でも false を返すことがあります。大文字・小文字を区別したくない場合は .equalsIgnoreCase() を使います。

Javaの文字列はなぜイミュータブル(変更不可)なのですか?

一度生成された String オブジェクトは決して変更できません。replacetoUpperCase のようなメソッドは、元のオブジェクトを変更するのではなく、新しい文字列を返します。イミュータブル性のおかげで文字列は安全に共有・キャッシュできますが、その分、結果を代入する必要があります:s = s.toUpperCase();。メソッドを呼び出して戻り値を無視すると、何も起こりません。

Javaで文字列の長さを取得するにはどうすればいいですか?

.length() メソッドを呼び出します:"hello".length()5 を返します。String ではこれは括弧付きのメソッドである点に注意してください。配列では length は括弧のないフィールド(arr.length)であり、扱いが異なります。

Coddy programming languages illustration

Coddyでコードを学ぼう

始める