NumberFormat と printf
NumberFormat、DecimalFormat、printf のパターンを使って、表示用に数値を整形します。
「NumberFormat と printf」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。
NumberFormatとprintf
Javaには、豊富な数値フォーマットAPIが用意されています。ロケールに対応した通貨やパーセントの表示にはNumberFormat、カスタムパターンにはDecimalFormat、C言語風のフォーマットにはprintf/String.formatを使用します。
String.formatの基本
String.format()は、フォーマット指定子を使用して文字列を組み立てます。一般的な指定子には、%d(整数)、%f(浮動小数点数)、%s(文字列)、%n(改行)があります。
String name = "Alice";
int score = 95;
double avg = 87.567;
String msg = String.format(
"Player: %s | Score: %d | Average: %.2f", name, score, avg);
System.out.println(msg);
// Player: Alice | Score: 95 | Average: 87.57
// printf is equivalent — formats directly to output
System.out.printf("%-10s %5d %8.2f%n", name, score, avg);
// Alice 95 87.57幅、パディング、位置揃え
フォーマット指定子では、幅と位置揃えのフラグを指定できます。%10d(10文字幅で右揃え)、%-10d(左揃え)、%010d(ゼロ埋め)などです。
// Table layout with padding
System.out.printf("%-20s %10s %10s%n", "Product", "Qty", "Price");
System.out.printf("%-20s %10d %10.2f%n", "Java Book", 3, 49.99);
System.out.printf("%-20s %10d %10.2f%n", "USB Hub", 1, 24.95);
System.out.printf("%-20s %10d %10.2f%n", "Mechanical Keyboard", 2, 129.00);
// Zero-padding for order IDs
int orderId = 42;
System.out.printf("Order: ORD-%08d%n", orderId); // Order: ORD-00000042通貨のためのNumberFormat
NumberFormat.getCurrencyInstance(Locale)は、指定したロケールに適した通貨記号、区切り文字、小数点以下の桁数を使って、数値を通貨文字列にフォーマットします。
import java.text.*;
import java.util.*;
NumberFormat usd = NumberFormat.getCurrencyInstance(Locale.US);
NumberFormat eur = NumberFormat.getCurrencyInstance(Locale.GERMANY);
NumberFormat gbp = NumberFormat.getCurrencyInstance(Locale.UK);
double amount = 1234567.89;
System.out.println(usd.format(amount)); // $1,234,567.89
System.out.println(eur.format(amount)); // 1.234.567,89 EUR
System.out.println(gbp.format(amount)); // GBP1,234,567.89パーセントのためのNumberFormat
NumberFormat.getPercentInstance()は、10進数をパーセント文字列にフォーマットします。0から1までの値を渡します。
import java.text.*;
import java.util.*;
NumberFormat pct = NumberFormat.getPercentInstance(Locale.US);
pct.setMaximumFractionDigits(1);
System.out.println(pct.format(0.75)); // 75%
System.out.println(pct.format(0.1234)); // 12.3%
System.out.println(pct.format(1.0)); // 100%
// Conversion rate in e-commerce
double convRate = 3_456.0 / 42_000.0;
System.out.println("Conversion: " + pct.format(convRate)); // 8.2%カスタムパターンによるDecimalFormat
DecimalFormatではパターン文字列を使用します。#は省略可能な数字、0は必須の数字を表します。
import java.text.*;
DecimalFormat df1 = new DecimalFormat("#,###.00");
System.out.println(df1.format(1234567.5)); // 1,234,567.50
DecimalFormat df2 = new DecimalFormat("000.0");
System.out.println(df2.format(7.5)); // 007.5
DecimalFormat df3 = new DecimalFormat("0.00E0");
System.out.println(df3.format(0.000123)); // 1.23E-4
// Scientific notation for large values
DecimalFormat sci = new DecimalFormat("0.000E0");
System.out.println(sci.format(123456789)); // 1.235E8文字列から数値を解析する
NumberFormatでは、ロケールに合わせてフォーマットされた文字列を数値に解析することもできます。異なるロケールでユーザー入力を読み取る場合に不可欠です。
import java.text.*;
import java.util.*;
NumberFormat nf = NumberFormat.getInstance(Locale.GERMANY);
try {
// German uses comma as decimal separator
Number parsed = nf.parse("1.234,56");
System.out.println(parsed.doubleValue()); // 1234.56
// Parse US currency string
NumberFormat usd = NumberFormat.getCurrencyInstance(Locale.US);
Number amount = usd.parse("$1,234.56");
System.out.println(amount.doubleValue()); // 1234.56
} catch (ParseException e) {
System.out.println("Parse error: " + e.getMessage());
}フォーマット済み文字列(Java 15以降)
Java 15以降では、String.format()のインスタンスメソッド版としてString.formatted()が追加されています。メソッドチェーンやストリームパイプラインで便利です。
record Product(String name, double price, int stock) {}
var products = List.of(
new Product("Laptop", 999.0, 5),
new Product("Mouse", 29.99, 42),
new Product("Monitor", 349.0, 8)
);
products.stream()
.map(p -> "%-15s $%8.2f [stock: %d]"
.formatted(p.name(), p.price(), p.stock()))
.forEach(System.out::println);
// Laptop $ 999.00 [stock: 5]
// Mouse $ 29.99 [stock: 42]
// Monitor $ 349.00 [stock: 8]数値のグループ化とロケール
数値のグループ化(桁区切り)はロケールによって異なります。ユーザー向けの出力では、カンマをハードコーディングするのではなく、必ずNumberFormatを使用します。
import java.text.*;
import java.util.*;
long users = 1_234_567;
for (Locale locale : new Locale[]{Locale.US, Locale.FRANCE, Locale.GERMANY}) {
NumberFormat nf = NumberFormat.getIntegerInstance(locale);
System.out.printf("%-10s: %s%n", locale, nf.format(users));
}
// en_US : 1,234,567
// fr_FR : 1 234 567
// de_DE : 1.234.567請求書生成の例
ここまでの内容を組み合わせ、通貨、パーセント、表の位置揃えを適切に設定した、フォーマット済みの請求書を生成します。
import java.text.*;
import java.util.*;
NumberFormat curr = NumberFormat.getCurrencyInstance(Locale.US);
NumberFormat pct = NumberFormat.getPercentInstance();
pct.setMaximumFractionDigits(0);
double subtotal = 1259.97;
double discount = 0.10;
double discountAmt = subtotal * discount;
double taxRate = 0.08;
double taxAmt = (subtotal - discountAmt) * taxRate;
double total = subtotal - discountAmt + taxAmt;
System.out.println("=== INVOICE ===");
System.out.printf("%-20s %15s%n", "Subtotal", curr.format(subtotal));
System.out.printf("%-20s %15s%n", "Discount (" + pct.format(discount) + ")",
"-" + curr.format(discountAmt));
System.out.printf("%-20s %15s%n", "Tax (" + pct.format(taxRate) + ")",
curr.format(taxAmt));
System.out.printf("%-20s %15s%n", "TOTAL", curr.format(total));よくある落とし穴
次のような、よくあるフォーマットのミスに注意してください。
- 誤った型指定子を使って
String.formatを呼び出すと(たとえばdoubleに%dを指定すると)、IllegalFormatConversionExceptionが発生します - ロケール固有のフォーマッターは、マシンによって異なる出力を生成します
- NumberFormatのインスタンスはスレッドセーフではありません。スレッドごとに1つ作成するか、
ThreadLocalを使用します
// Wrong specifier
try {
String.format("%d", 3.14); // IllegalFormatConversionException
} catch (java.util.IllegalFormatConversionException e) {
System.out.println("Wrong format specifier!");
}
// Thread-safe pattern using ThreadLocal
ThreadLocal<NumberFormat> localFmt = ThreadLocal
.withInitial(() -> NumberFormat.getCurrencyInstance(Locale.US));
// each thread gets its own NumberFormat instanceクイックチェック
String.format("%08.2f", 3.5)の結果はどうなりますか。
まとめ:NumberFormatとprintf
重要なポイント:
- String.format / printfでは、%d、%f、%s、%.2fなどのフォーマット指定子を使用します
- 幅と位置揃えのフラグには、%10d(右揃え)、%-10d(左揃え)、%010d(ゼロ埋め)があります
- ロケールに対応した通貨表示にはNumberFormat.getCurrencyInstance()を使用します
- パーセント表示にはNumberFormat.getPercentInstance()を使用します
- DecimalFormatでは、#(省略可能)と0(必須)の数字パターンを使用します
- NumberFormatでは、ロケールに合わせてフォーマットされた文字列を数値に解析することもできます
よくある質問
「NumberFormat と printf」レッスンは無料ですか?
はい。「NumberFormat と printf」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。
「NumberFormat と printf」で何を学びますか?
NumberFormat、DecimalFormat、printf のパターンを使って、表示用に数値を整形します。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Java Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「NumberFormat と printf」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このJava Academyレッスンでコードを書いて実行できますか?
はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Math クラスの基本
- 整数演算とオーバーフロー
- 金額計算のための BigDecimal
- NumberFormat と printf