1. 手動連結の問題
1~2個の変数を出力するだけなら、演算子 + は確かに便利です。しかし、データが多くなると連結はすぐにカオスになり、特に数値の書式(例: 小数点以下2桁)や改行が必要な場合はなおさらです。
String name = "Oleg";
int age = 25;
double balance = 12345.67;
System.out.println("名前: " + name + ", 年齢: " + age + ", 残高: " + balance + " ユーロ。");
手動連結の中で書式を「後付け」しようとすると、可読性はさらに悪化します:
System.out.println("名前: " + name + ", 年齢: " + age + ", 残高: " + String.format("%.2f", balance) + " ユーロ。");
結論: 単純な連結は小さな用途には良いですが、複雑なメッセージにはより強力なツール — String.format() が必要です。
2. String.format — 本格的に文字列を整形する
メソッド String.format() を使うと、テンプレートに従って文字列を作成し、指定位置に値を差し込めます。
一般形:
String result = String.format("テンプレート", 値...);
- %s — 文字列
- %d — 整数
- %f — 浮動小数点数
- %n — 改行(クロスプラットフォーム)
String name = "Oleg";
int age = 25;
double balance = 12345.6789;
String info = String.format("名前: %s, 年齢: %d, 残高: %.2f ユーロ。", name, age, balance);
System.out.println(info);
// 出力: 名前: Oleg, 年齢: 25, 残高: 12345.68 ユーロ。
String result = String.format("名前: %s, 年齢: %d, 残高: %.2f ユーロ", name, age, balance);
// %s — 文字列、%d — 整数、%.2f — 小数点以下2桁の数値
数値と文字列のフォーマット
固定精度の小数:
double price = 99.999;
System.out.println(String.format("価格: %.2f ユーロ。", price)); // 出力: 価格: 100.00 ユーロ。
フィールド幅と配置:
int n = 7;
System.out.println(String.format("数値: [%5d]", n)); // 数値: [ 7]
System.out.println(String.format("数値: [%-5d]", n)); // 数値: [7 ]
[5d] — フィールド幅は 5、既定は右寄せ。
[-5d] — フィールド幅は 5、左寄せ。
文字列の配置:
String text = "Java";
System.out.println(String.format("[%10s]", text)); // [ Java]
System.out.println(String.format("[%-10s]", text)); // [Java ]
パーセント:
double percent = 0.125;
System.out.println(String.format("完了: %.1f%%", percent * 100)); // 完了: 12.5%
パーセント記号を表示するには %% を使います。
日付のフォーマット(簡単に)
import java.util.Date;
Date now = new Date();
System.out.println(String.format("本日: %tD", now)); // 本日: 06/18/24
System.out.println(String.format("時刻: %tT", now)); // 時刻: 15:42:07
ローカライズと区切り記号
既定ではシステムのロケールが使われます。独自に指定したい場合(例: 小数点の区切りをカンマにしたい)、ロケールを第1引数で渡します。例: Locale.FRANCE。
import java.util.Locale;
double price = 1234.56;
System.out.println(String.format(Locale.FRANCE, "%.2f", price)); // 1234,56
実用的な例
例 1: 簡易レポート
String name = "Anna";
int tasks = 5;
double hours = 12.3456;
String report = String.format(
"担当者: %s%n完了したタスク数: %d%n消費時間: %.1f",
name, tasks, hours
);
System.out.println(report);
/* 出力:
担当者: Anna
完了したタスク数: 5
消費時間: 12.3
*/
例 2: 揃え付きの表
String header = String.format("%-10s | %5s | %8s", "名前", "スコア", "時間");
String row1 = String.format("%-10s | %5d | %8.2f", "Oleg", 95, 10.5);
String row2 = String.format("%-10s | %5d | %8.2f", "Anna", 100, 9.75);
System.out.println(header);
System.out.println(row1);
System.out.println(row2);
/* 出力:
名前 | スコア | 時間
Oleg | 95 | 10.50
Anna | 100 | 9.75
*/
例 3: 混在したテキスト
int apples = 12;
int pears = 8;
System.out.println(String.format("私はリンゴが%d個、ナシが%d個あります。", apples, pears));
3. 実践: アプリで文字列をフォーマットする
コンソールアプリにフォーマットを追加します。残高は常に小数点以下2桁、改行は %n を使います。
Scanner console = new Scanner(System.in);
System.out.print("名前を入力してください: ");
String name = console.nextLine();
System.out.print("年齢を入力してください: ");
int age = console.nextInt();
System.out.print("残高を入力してください: ");
double balance = console.nextDouble();
// 書式化した出力
String info = String.format("名前: %s、年齢: %d、残高: %.2f ユーロ。", name, age, balance);
System.out.println(info);
試してみよう:
- さまざまな値を入力して、残高が常に小数点以下2桁(%.2f)で出力されることを確認する。
- テンプレートを変更して、%n を使った改行を追加する。
4. 文字列フォーマットでのよくあるエラー
エラー № 1: 型と書式指定子の不一致。
文字列を %d に、数値を %s に渡すことはできません。
String.format("年齢: %d", "twenty"); // エラー: 数値が期待されたが、文字列が渡された
エラー № 2: 引数の順序を取り違えた。
書式が %s %d なのに、先に数値、次に文字列を渡すと — エラーになるか、誤った出力になります。
エラー № 3: ロケールを無視した。
小数点の区切りにカンマを期待しているのにピリオドになる場合は、必要なロケールを第1引数で明示的に渡してください(String.format(...))。
エラー № 4: パーセント記号のエスケープ漏れ。
記号 % を出力するには %% を使います。そうしないとフォーマット処理はエラーで失敗します。
GO TO FULL VERSION