杰瑞科技汇

Java中如何格式化数字?

System.out.printf()String.format() - 最常用

这是最直接、最简单的方法,类似于 C 语言中的 printf,它使用格式化字符串来定义输出格式。

核心语法: %[flags][width][.precision]conversion

  • conversion (转换字符): 必须的,指定如何格式化。

    • d: 整数 (decimal)
    • f: 浮点数 (float)
    • eE: 科学计数法
    • gG: 通用格式,自动在 fe 之间选择
    • s: 字符串 (String)
    • bB: 布尔值 (Boolean)
    • cC: 字符 (Character)
    • xX: 十六进制整数
    • o: 八进制整数
  • width (宽度): 最小字符数,如果数字长度小于此值,则用空格填充(默认右对齐)。

  • .precision (精度):

    • 对于 f, e, g,表示小数点后保留的位数。
    • 对于 s,表示最大字符数。
  • flags (标志):

    • 左对齐(默认右对齐)
    • 总是显示正负号
    • ` (空格): 正数前加一个空格,负数前加负号(与+` 互斥)
    • 添加千位分隔符 (1,000,000)
    • 将负数用括号括起来
    • 0: 用零填充(而不是空格)

示例代码

public class NumberFormatting {
    public static void main(String[] args) {
        double price = 12345.6789;
        int quantity = 9876;
        double percentage = 0.87654321;
        // 1. 基本浮点数格式化
        System.out.println("--- 基本浮点数 ---");
        System.out.printf("原始值: %f%n", price); // 默认保留6位小数
        System.out.printf("保留2位小数: %.2f%n", price);
        System.out.printf("保留0位小数: %.0f%n", price); // 会四舍五入
        // 2. 整数格式化
        System.out.println("\n--- 整数格式化 ---");
        System.out.printf("原始值: %d%n", quantity);
        System.out.printf("宽度为10,右对齐: %10d%n", quantity);
        System.out.printf("宽度为10,左对齐: %-10d%n", quantity);
        System.out.printf("总显示正负号: %+d%n", quantity);
        System.out.printf("总显示正负号,宽度为10: %+10d%n", quantity);
        System.out.printf("千位分隔符: %,d%n", quantity); // 9,876
        // 3. 科学计数法
        System.out.println("\n--- 科学计数法 ---");
        System.out.printf("默认科学计数法: %e%n", price);
        System.out.printf("大写E,保留2位小数: %.2E%n", price);
        // 4. 通用格式
        System.out.println("\n--- 通用格式 ---");
        System.out.printf("通用格式g: %g%n", price);
        System.out.printf("通用格式G: %G%n", price);
        // 5. 组合使用:格式化货币
        System.out.println("\n--- 组合使用示例 ---");
        System.out.printf("价格: ¥%,.2f%n", price);
        System.out.printf("折扣: %d%% (原价: ¥%,.2f)%n", (int)(percentage * 100), price);
        // 6. 使用 String.format() 获取格式化后的字符串
        System.out.println("\n--- String.format() ---");
        String formattedString = String.format("商品数量: %, 件,总价: ¥%,.2f", quantity, price);
        System.out.println(formattedString);
    }
}

输出结果:

--- 基本浮点数 ---
原始值: 12345.678900
保留2位小数: 12345.68
保留0位小数: 12346
--- 整数格式化 ---
原始值: 9876
宽度为10,右对齐:       9876
宽度为10,左对齐: 9876      
总显示正负号: +9876
总显示正负号,宽度为10:     +9876
千位分隔符: 9,876
--- 科学计数法 ---
默认科学计数法: 1.234568e+04
大写E,保留2位小数: 1.23E+04
--- 通用格式 ---
通用格式g: 12345.7
通用格式G: 12345.7
--- 组合使用示例 ---
价格: ¥12,345.68
折扣: 88% (原价: ¥12,345.68)
--- String.format() ---
商品数量: 9,876 件,总价: ¥12,345.68

DecimalFormat 类 - 更灵活,用于本地化

java.text.DecimalFormat 是一个功能更强大的类,特别适合需要复杂格式化规则(如本地化货币、百分号、自定义模式)的场景,它使用模式字符串来定义格式。

核心步骤:

  1. import java.text.DecimalFormat;
  2. 创建 DecimalFormat 实例,传入模式字符串。
  3. 调用 format() 方法。

示例代码

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
public class DecimalFormatExample {
    public static void main(String[] args) {
        double number = 1234567.891;
        int integer = 987654321;
        // 1. 基本模式
        System.out.println("--- 基本模式 ---");
        DecimalFormat df1 = new DecimalFormat("###,###.##"); // 任意数字,千位分隔,2位小数
        System.out.println(df1.format(number)); // 1,234,567.89
        DecimalFormat df2 = new DecimalFormat("000,000.000"); // 固定宽度,不足补0
        System.out.println(df2.format(number)); // 1,234,567.891
        // 2. 百分比模式
        System.out.println("\n--- 百分比模式 ---");
        double percentage = 0.789;
        DecimalFormat percentFormat = new DecimalFormat("#0.00%");
        System.out.println(percentFormat.format(percentage)); // 78.90%
        // 3. 货币模式
        System.out.println("\n--- 货币模式 ---");
        // 使用 NumberFormat 的工厂方法获取特定地区的货币格式
        NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(Locale.CHINA);
        System.out.println(currencyFormat.format(number)); // ¥1,234,567.89
        NumberFormat currencyFormatUS = NumberFormat.getCurrencyInstance(Locale.US);
        System.out.println(currencyFormatUS.format(number)); // $1,234,567.89
        // 4. 科学计数法
        System.out.println("\n--- 科学计数法 ---");
        DecimalFormat scientificFormat = new DecimalFormat("0.###E0");
        System.out.println(scientificFormat.format(number)); // 1.235E6
        // 5. 自定义模式(负数显示为红色括号,但控制台不支持颜色,这里用括号代替)
        System.out.println("\n--- 自定义模式 ---");
        double profit = 15000;
        double loss = -5000;
        DecimalFormat profitLossFormat = new DecimalFormat("###,###.00;###,###.00"); // 分号分隔正负格式
        System.out.println("利润: " + profitLossFormat.format(profit)); // 利润: 15,000.00
        System.out.println("亏损: " + profitLossFormat.format(loss)); // 亏损: 5,000.00 (注意,这里只是格式,没有括号)
        // 更精确的自定义
        DecimalFormat customFormat = new DecimalFormat("#,##0.00;(#,##0.00)");
        System.out.println("亏损(自定义): " + customFormat.format(loss)); // 亏损(自定义): (5,000.00)
    }
}

输出结果:

--- 基本模式 ---
1,234,567.89
1,234,567.891
--- 百分比模式 ---
78.90%
--- 货币模式 ---
¥1,234,567.89
$1,234,567.89
--- 科学计数法 ---
1.235E6
--- 自定义模式 ---
利润: 15,000.00
亏损: 5,000.00
亏损(自定义): (5,000.00)

NumberFormat 类 - 国际化友好

java.text.NumberFormat 是一个抽象基类,它提供了很多静态工厂方法来获取不同风格的格式化器,特别适合处理国际化(i18n)问题。

  • NumberFormat.getInstance(): 获取通用数字格式。
  • NumberFormat.getCurrencyInstance(): 获取货币格式。
  • NumberFormat.getPercentInstance(): 获取百分比格式。
  • NumberFormat.getIntegerInstance(): 获取整数格式。

它内部会根据 Locale(地区)自动使用正确的千位分隔符、小数点符号和货币符号。


示例代码

import java.text.NumberFormat;
import java.util.Locale;
public class NumberFormatExample {
    public static void main(String[] args) {
        double number = 1234567.89;
        double percentage = 0.5678;
        // 1. 通用数字格式
        System.out.println("--- 通用数字格式 ---");
        NumberFormat generalFormat = NumberFormat.getInstance();
        System.out.println("默认地区: " + generalFormat.format(number)); // 1,234,567.89
        NumberFormat germanFormat = NumberFormat.getInstance(Locale.GERMANY);
        System.out.println("德国地区: " + germanFormat.format(number)); // 1.234.567,89
        // 2. 货币格式
        System.out.println("\n--- 货币格式 ---");
        NumberFormat currencyFormatCN = NumberFormat.getCurrencyInstance(Locale.CHINA);
        System.out.println("中国货币: " + currencyFormatCN.format(number)); // ¥1,234,567.89
        NumberFormat currencyFormatUS = NumberFormat.getCurrencyInstance(Locale.US);
        System.out.println("美国货币: " + currencyFormatUS.format(number)); // $1,234,567.89
        NumberFormat currencyFormatJP = NumberFormat.getCurrencyInstance(Locale.JAPAN);
        System.out.println("日本货币: " + currencyFormatJP.format(number)); // ¥1,234,568
        // 3. 百分比格式
        System.out.println("\n--- 百分比格式 ---");
        NumberFormat percentFormat = NumberFormat.getPercentInstance();
        System.out.println("默认百分比: " + percentFormat.format(percentage)); // 56.78%
        NumberFormat frenchPercentFormat = NumberFormat.getPercentInstance(Locale.FRANCE);
        System.out.println("法国百分比: " + frenchPercentFormat.format(percentage)); // 56,78 %
        // 4. 整数格式
        System.out.println("\n--- 整数格式 ---");
        NumberFormat integerFormat = NumberFormat.getIntegerInstance();
        System.out.println("整数格式: " + integerFormat.format(number)); // 1,234,568
    }
}

输出结果:

--- 通用数字格式 ---
默认地区: 1,234,567.89
德国地区: 1.234.567,89
--- 货币格式 ---
中国货币: ¥1,234,567.89
美国货币: $1,234,567.89
日本货币: ¥1,234,568
--- 百分比格式 ---
默认百分比: 56.78%
法国百分比: 56,78 %
--- 整数格式 ---
整数格式: 1,234,568

总结与选择建议

方法 优点 缺点 适用场景
printf / String.format 语法简洁,直接嵌入代码 功能相对固定,国际化支持弱 简单的控制台输出、日志、快速格式化字符串。
DecimalFormat 功能强大,模式非常灵活(如自定义符号、科学计数法) 需要创建对象,模式字符串学习成本稍高 需要复杂、非标准的数字格式,如特定报表格式、自定义百分比显示。
NumberFormat 国际化支持最好,自动适配地区 功能相对 DecimalFormat 较弱,灵活性低 需要显示给用户的、面向国际化的界面,如货币、百分比、通用数字。

简单选择指南:

  • 只是想在控制台打印一下,或者快速生成一个格式化的字符串?

    • System.out.printf()String.format(),这是最简单直接的方式。
  • 需要处理货币、百分比,并且希望程序在不同国家/地区都能正确显示?

    • NumberFormat,这是国际化应用的最佳选择。
  • 需要非常自定义的格式, 或者特定格式的科学计数法?

    • DecimalFormat,它提供了最大的控制力。
分享:
扫描分享到社交APP
上一篇
下一篇