String.format で書式化
桁の大きい数字を、そのまま出すと読めない
+ での連結はもう自由に書けるようになりました。ところが画面に数字を出す段になると、+ だけでは足りない場面が出てきます。
Java
System.out.println("売上 " + 1234567 + " 円");
// 売上 1234567 円1234567 が何百万なのか、目で数えないと分かりません。3 桁ごとに区切りたい、小数を 2 桁で止めたい、伝票番号の桁を揃えたい。こうした「最後のひと整え」を引き受けるのが String.format です。
% の場所に、引数が順番に入る
String.format は、第 1 引数に型枠を書いた文字列を渡し、第 2 引数から値を順番に並べます。% で始まる印が置いてある場所に、値が前から順に流し込まれます。
Java
String a = String.format("%s さんの平均は %.1f 点です", "田中", 87.25);
// 田中 さんの平均は 87.3 点です
String b = String.format("売上 %,d 円", 1234567);
// 売上 1,234,567 円
String c = String.format("伝票番号 %05d", 42);
// 伝票番号 00042課題で必要になるのは次の 4 つです。%s は文字列をそのまま入れます。%d は整数を入れます。%,d は整数を 3 桁ごとにカンマで区切ります。%.1f は小数を 1 桁に丸めます。丸める桁を増やしたければ %.2f のように数字を変えるだけです。
%05d の 0 と 5 は「5 桁になるまで 0 で埋める」という指定です。カンマの , も 0 も % と d の間に書く飾りで、順番はフラグ、幅、精度、型と決まっています。全部を覚える必要はなく、必要になったときに 1 つずつ足していけば足ります。
型が合っていなくても、コンパイルは通る
String.format の落とし穴は、間違いが実行時まで表に出ないことです。
Java
String.format("%d 件", "100"); // 実行時に IllegalFormatConversionException
String.format("%s と %s", "java"); // 実行時に MissingFormatArgumentException%d の場所に文字列を渡しても、コンパイルは通ってしまいます。逆に %s は何でも受け取れるので、型に自信がないときの逃げ道になります。
印の数より引数が少ないときも実行時に落ちます。多すぎる場合はエラーにならず、余った引数が黙って無視されます。書いたら一度目で追って、印と値を 1 対 1 で数え合わせるのが確実です。
似た
System.out.printfは、整形した結果をその場で画面に流すだけで、文字列を返しません。戻り値をテストで比べる課題では使えないので、文字列がほしいときはString.formatを選びます。
課題では、受け取った値を 1 本の文字列に組み立てて返します。区切りのカンマが要る場所で %d を書いてしまうとカンマが出ず、期待した表示になりません。どの印を使うかだけ、先に決めてから書き始めてください。
要件
- クラス名は
Solution、メソッド名はpriceLabel、引数はString name, int priceの 2 つ、戻り値の型はStringにすること - 本文中で示した
String.format("%s: ¥%,d", name, price)の書式指定子を使って整形すること (+連結やStringBuilderは使わない) %,dのカンマフラグを必ず付け、120000が"120,000"のように千の位区切りで表示されるようにすること
入出力例
priceLabel("リンゴ", 100) → "リンゴ: ¥100"
priceLabel("ノートPC", 120000) → "ノートPC: ¥120,000"
priceLabel("", 0) → ": ¥0"
priceLabel("コーヒー", 1234) → "コーヒー: ¥1,234"
priceLabel("冷蔵庫", 1500000) → "冷蔵庫: ¥1,500,000"