String 操作(concat, substring, format) — 表示・ログ処理
文字列は「表示」「ログ」「メッセージ生成」で毎日のように使います。Javaの代表的な操作である concat(結合)、substring(切り出し)、format(整形)の基本から、初心者がつまずきやすいポイントまでまとめます。
文字列の結合(concat と + と StringBuilder)
基本の結合
String a = "Hello";
String b = "World";
String c1 = a.concat(" ").concat(b); // "Hello World"
String c2 = a + " " + b; // "Hello World"
Java- 使い分けの目安:
- 少ない回数の結合:
+またはconcat。 - 繰り返しや大量結合: StringBuilder(パフォーマンスが安定)。
- 少ない回数の結合:
繰り返し結合(ログやCSV生成)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 5; i++) {
sb.append("item").append(i).append(",");
}
String line = sb.toString(); // "item0,item1,item2,item3,item4,"
Java- 注意点:
- String は不変: 結合のたびに新しいインスタンスができる。繰り返しは StringBuilder を使う。
- null の結合:
concatは引数が null だと例外になる。+は “null” と文字になることに注意。
文字列の切り出し(substring)とインデックス
基本の使い方
String s = "ABCDE";
String s1 = s.substring(0, 3); // "ABC" [開始含む, 終了は含まない]
String s2 = s.substring(2); // "CDE" [2から末尾まで]
Java- インデックスのルール:
- 開始は含む、終了は含まない。
- 範囲外のインデックスは例外。開始 > 終了でも例外。
部分抽出の定番(前後の固定長)
String code = "JP-2025-0001";
String country = code.substring(0, 2); // "JP"
String year = code.substring(3, 7); // "2025"
String seq = code.substring(8); // "0001"
Java位置検索と組み合わせ(indexOf)
String email = "user@example.com";
int at = email.indexOf('@'); // 4
String user = email.substring(0, at); // "user"
String domain = email.substring(at + 1); // "example.com"
Java- 注意点:
- 見つからない場合:
indexOfは -1 を返す。-1のまま substring すると例外。 - 境界チェック: 事前に条件で守る。
- 見つからない場合:
文字列の整形(String.format と printf)
プレースホルダで整形
String msg = String.format("ID=%d, name=%s, price=%.2f", 101, "Book", 1999.5);
// "ID=101, name=Book, price=1999.50"
System.out.printf("Hello %s (%d)%n", "Tanaka", 20); // コンソールへ出力
Java- 主なプレースホルダ:
- %s: 文字列
- %d: 整数
- %f: 小数(
%.2fは小数点以下2桁) - %n: 改行(環境依存の改行コード)
桁揃え・ゼロ埋め
String id = String.format("ORD-%05d", 42); // "ORD-00042"
String col = String.format("|%-10s|%10s|", "left", "right");
// 左寄せ・右寄せの例
Javaロケール(小数点/通貨の違い)
import java.util.Locale;
String jp = String.format(Locale.JAPAN, "%,.2f", 1234567.89); // "1,234,567.89"
String de = String.format(Locale.GERMANY, "%,.2f", 1234567.89); // "1.234.567,89"
Java- 注意点:
- Locale を指定すると表記が変わる(区切り・小数点)。
- 通貨や日時は
NumberFormat/DateTimeFormatterの利用も検討。
よく使う補助操作(replace, split, join, trim)
置換・削除
String phone = "03-1234-5678";
String noDash = phone.replace("-", ""); // "0312345678"
Java分割
String csv = "A,B,C";
String[] parts = csv.split(","); // ["A","B","C"]
Java結合(join)
String line = String.join("/", "2025", "12", "04"); // "2025/12/04"
Java余白除去(trim)
String raw = " hello ";
String t = raw.trim(); // "hello"
Java- 注意点:
- split の正規表現: 例えば
split("|")は特殊文字。区切りが|の場合はsplit("\\|")。 - replace と replaceAll: 後者は正規表現。単純置換なら
replaceが安全。
- split の正規表現: 例えば
表示・ログの実践パターン
ログのメッセージ組み立て
String userId = "u-001";
String action = "login";
String log = String.format("[%s] action=%s, at=%d", userId, action, System.currentTimeMillis());
System.out.println(log);
Java- ポイント:
- format で構造を明確に。
- 時刻やIDなどのキー情報を抜けなく入れる。
テンプレート化(定型メッセージ)
String template = "Order %s for %s is %s.";
String msg1 = String.format(template, "ORD-42", "Tanaka", "confirmed");
String msg2 = String.format(template, "ORD-43", "Sato", "pending");
Java- ポイント:
- ひな形を一箇所に。複数箇所で同じ書式を乱立させない。
例題で身につける(解説つき)
例題1: 顧客表示名の生成(氏名+顧客ID)
String first = "Taro";
String last = "Yamada";
int id = 27;
String display = String.format("%s %s (#%04d)", first, last, id);
// "Taro Yamada (#0027)"
Java- ポイント: format のゼロ埋めで見やすい識別子に。
例題2: メールドメイン抽出(indexOf+substring)
String email = "alice@company.co.jp";
int pos = email.indexOf('@');
if (pos >= 0) {
String domain = email.substring(pos + 1);
System.out.println(domain); // "company.co.jp"
} else {
System.out.println("メール形式ではありません");
}
Java- ポイント: 見つからない場合の -1 チェックを忘れない。
例題3: 売上レコードのCSV行生成(StringBuilder)
String[] fields = {"INV-1001", "2025-12-04", "9800"};
StringBuilder sb = new StringBuilder();
for (int i = 0; i < fields.length; i++) {
if (i > 0) sb.append(",");
sb.append(fields[i]);
}
String csvLine = sb.toString(); // "INV-1001,2025-12-04,9800"
Java- ポイント: 繰り返し結合は StringBuilder。区切りの扱いは「先頭だけ除外」などのパターンを使う。
例題4: ロケール別の数値表示(format+Locale)
double amount = 1234567.0;
System.out.println(String.format(Locale.JAPAN, "%,.0f", amount)); // "1,234,567"
System.out.println(String.format(Locale.GERMANY, "%,.0f", amount)); // "1.234.567"
Java- ポイント: ユーザーの地域に合わせるなら Locale 指定。
テンプレート集(すぐ使える雛形)
連結の基本形
String result = a.concat(b); // null 非許容
String result2 = a + b; // 手軽だが繰り返しは非推奨
Javaループ結合(可変長)
StringBuilder sb = new StringBuilder();
for (String v : values) sb.append(v);
String out = sb.toString();
Java切り出し(安全なインデックス)
int p = s.indexOf(marker);
if (p >= 0) {
String left = s.substring(0, p);
String right = s.substring(p + marker.length());
}
Java整形(プレースホルダ)
String msg = String.format("user=%s, count=%d, rate=%.1f%%", user, count, rate);
Javaありがちな落とし穴と対処
- 落とし穴: concat に null を渡すと例外。
- 対処: null を事前に置換してから結合(例:
Objects.toString(x, ""))。
- 対処: null を事前に置換してから結合(例:
- 落とし穴: substring の終了インデックスを含むと誤解。
- 対処: 「終了は含まない」を覚える。境界チェックを入れる。
- 落とし穴:
split("|")など正規表現の特殊文字。- 対処: エスケープ(
"\\|")またはPattern.quote(delimiter)を使う。
- 対処: エスケープ(
- 落とし穴: 大量連結を
+で書いて遅い。- 対処: StringBuilder に置き換え。または
String.joinを使う。
- 対処: StringBuilder に置き換え。または
- 落とし穴: ロケール未指定で表記ズレ。
- 対処: Locale を明示、または国際化方針に従う。
まとめ
- concat / +: 少量結合に向く。null と不変性に注意。
- StringBuilder: 反復結合の王道。
- substring: 開始含む/終了含まない。indexOf とセットで安全に。
- format / printf: プレースホルダで読みやすく。桁揃えや Locale 指定が効く。
