この記事の要点
• String は不変(immutable)オブジェクト。一度作ったら内容は変わらない
• 比較は .equals() を使う。== は同一性のチェック
• 主要メソッド(length / substring / indexOf)を覚えれば基本操作は完結
このシリーズについて
「Java入門」は1本1テーマで進む全15回のシリーズです。本記事はその第5回として、Javaで最も頻繁に扱う**文字列(String)**の基本操作を解説します。
前提条件: Java入門 #1 - 開発環境構築 でJDK 21 がインストール済み。変数とデータ型の基礎を理解済み。
Stringとは
Javaでは文字列を扱うために String クラスを使います。ダブルクォート(")で囲んだものが文字列リテラルとして認識されます。
// Java 21
String greeting = "こんにちは";
String name = "太郎";
String は参照型であり、不変(immutable) です。一度作成した文字列の内容を変更することはできません。
ポイント: 文字列を変更したい場合は、新しい String オブジェクトが生成されます。元の文字列自体は変わりません。
文字列の生成
String は3つの方法で生成できます。
| 方法 | 構文 | 推奨度 |
|---|---|---|
| リテラル | String s = "Hello"; | ★★★ |
| コンストラクタ | String s = new String("Hello"); | △(非推奨) |
| 他の型から変換 | String.valueOf(123) | ★★ |
リテラルを使うのが最も一般的で、文字列プールにより効率的です。
// 推奨
String message = "Hello, World!";
// 非推奨(メモリ効率が悪い)
String message2 = new String("Hello, World!");
文字列の連結
+ 演算子で文字列を連結できます。
String first = "Hello";
String second = "World";
String result = first + ", " + second + "!"; // "Hello, World!"
補足: Java 15以降、コンパイラが内部的に StringBuilder を使うため、複数の + でも効率的です。ループ内で大量に連結する場合のみ StringBuilder を明示的に使いましょう。
主要メソッド一覧
String クラスには多くのメソッドがありますが、まず覚えるべきものは以下の10個です。
| メソッド | 説明 | 戻り値 |
|---|---|---|
length() | 文字列の長さを返す | int |
charAt(int index) | 指定位置の文字を返す(0始まり) | char |
substring(int beginIndex) | 指定位置から末尾までの部分文字列 | String |
substring(int beginIndex, int endIndex) | 指定範囲の部分文字列(endIndexは含まない) | String |
indexOf(String str) | 指定文字列が最初に出現する位置(見つからなければ-1) | int |
equals(Object obj) | 内容が同じかを比較 | boolean |
equalsIgnoreCase(String str) | 大文字小文字を無視して比較 | boolean |
trim() | 前後の空白を除去 | String |
toUpperCase() | すべて大文字に変換 | String |
toLowerCase() | すべて小文字に変換 | String |
実例:基本操作
以下のコードで主要メソッドの使い方を確認します。
// Java 21
public class StringBasics {
public static void main(String[] args) {
String message = "Hello, Java 21!";
// 長さを取得
int len = message.length();
System.out.println("長さ: " + len); // 16
// 指定位置の文字を取得(0始まり)
char firstChar = message.charAt(0);
System.out.println("最初の文字: " + firstChar); // 'H'
// 部分文字列を取得
String sub1 = message.substring(7); // "Java 21!"
String sub2 = message.substring(7, 11); // "Java"(11は含まない)
System.out.println("substring(7): " + sub1);
System.out.println("substring(7, 11): " + sub2);
// 文字列の検索
int index = message.indexOf("Java");
System.out.println("'Java' の位置: " + index); // 7
// 見つからない場合
int notFound = message.indexOf("Python");
System.out.println("'Python' の位置: " + notFound); // -1
}
}
実行すると以下のように出力されます。
長さ: 16
最初の文字: H
substring(7): Java 21!
substring(7, 11): Java
'Java' の位置: 7
'Python' の位置: -1
文字列の比較:equals() vs ==
重要: 文字列の内容を比較するには equals() を使います。== は同一のオブジェクトかどうかを判定するため、内容が同じでも false になることがあります。
// Java 21
public class StringComparison {
public static void main(String[] args) {
String s1 = "Hello";
String s2 = "Hello";
String s3 = new String("Hello");
// リテラルは文字列プールを共有するので同じオブジェクト
System.out.println(s1 == s2); // true(同じ参照)
System.out.println(s1.equals(s2)); // true(内容が同じ)
// new String() は別オブジェクトを生成
System.out.println(s1 == s3); // false(異なる参照)
System.out.println(s1.equals(s3)); // true(内容が同じ)
}
}
注意: 文字列の比較に == を使うと意図しない動作になる可能性があります。必ず equals() を使いましょう。
大文字小文字を無視した比較
equalsIgnoreCase() を使うと、大文字小文字の違いを無視して比較できます。
String a = "Java";
String b = "JAVA";
System.out.println(a.equals(b)); // false
System.out.println(a.equalsIgnoreCase(b)); // true
前後の空白を除去:trim()
trim() は文字列の前後にある空白(スペース、タブ、改行)を除去した新しい文字列を返します。
String input = " Hello ";
String trimmed = input.trim();
System.out.println("'" + trimmed + "'"); // 'Hello'
ポイント: Java 11以降では strip() / stripLeading() / stripTrailing() も利用できます。これらはUnicodeの空白文字にも対応しています。
大文字・小文字変換
String text = "Hello World";
System.out.println(text.toUpperCase()); // "HELLO WORLD"
System.out.println(text.toLowerCase()); // "hello world"
実例:ユーザー入力の正規化
実際のプログラムでは、ユーザーが入力した文字列を整形してから処理することがよくあります。
// Java 21
import java.util.Scanner;
public class InputNormalization {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("名前を入力してください: ");
String input = scanner.nextLine();
// 前後の空白を削除し、すべて小文字に変換
String normalized = input.trim().toLowerCase();
if (normalized.equals("admin")) {
System.out.println("管理者としてログインしました");
} else {
System.out.println("ようこそ、" + input.trim() + "さん");
}
scanner.close();
}
}
このコードは以下を実現しています。
trim()で余分な空白を除去toLowerCase()で大文字小文字を統一equals()で安全に比較
よくあるミス
| ミス | 正しい書き方 |
|---|---|
if (s == "Hello") | if (s.equals("Hello")) |
s[0] で文字を取得 | s.charAt(0) |
substring(7, 10) で10文字目を含む | substring(7, 11)(終了indexは含まない) |
| 文字列を変更しようとする | 新しいStringを生成する |
次のステップ
Java入門 #6 - 条件分岐(if / else if / else) で、文字列の比較結果をもとに処理を分岐させる方法を学びます。
参考リソース
- String (Java SE 21) - Oracle Docs — 公式APIドキュメント
- The Java Tutorials - Strings — Oracle公式チュートリアル
- StringBuilder (Java SE 21) — 大量の連結が必要な場合