Java 详解数字格式化(NumberFormat&DecimalFormat)

Posted ZSYL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 详解数字格式化(NumberFormat&DecimalFormat)相关的知识,希望对你有一定的参考价值。


对于 DecimalFormat类的使用,学了之后,也放了很久,不经常用,忘得差不多了,最近比赛用到数据格式化,小数点保留指定位数,所以重新拾起来,复习一下。

前言

查看官方 API 发现:
Java对文字,数字的格式化,是有一个公共的父类的 Format
在这里插入图片描述

NumberFormatDecimalFormat都是它的子类关于数字的。
DateFormatSimpleDateFormat也是它的子类关于文字的。

要特别注意的是 NumberFormat和DecimalFormat 是线程不安全的。 这意味你如果同时有多个线程操作一个format实例对象,会出现意想不到的结果。

NumberFormat

NumberFormat帮助您格式化和解析任何区域设置的数字。您的代码可以完全独立于小数点,千位分隔符的区域设置约定,甚至是使用的特定十进制数字,或者数字格式是否为十进制。

NumberFormat是所有数字格式的抽象基类。 该类提供格式化和解析数字的接口。
NumberFormat还提供了确定哪些区域设置具有数字格式以及它们的名称的方法。
NumberFormat可帮助您格式化和解析任何区域设置的数字。 您的代码可以完全独立于小数点,数千分隔符或甚至使用的特定十进制数字的区域设置约定,或者数字格式是否为偶数十进制。

获取NumberFormat实例

//创建 一个整数格式,地区用系统默认的 NumberFormat实例对象
NumberFormat integerNumber = NumberFormat.getIntegerInstance(Locale.getDefault());
  1. 使用getInstance或getNumberInstance获取正常的数字格式。
  2. 使用getIntegerInstance得到的整数格式。
  3. 使用getCurrencyInstance来获取货币数字格式。
  4. 使用getPercentInstance获取显示百分比的格式。

在这里插入图片描述
---- Java 官方API

使用示例

NumberFormat numberFormat = NumberFormat.getInstance(Locale.getDefault());
// 整数部分不会每隔三个,就会有 " ,"
numberFormat.setGroupingUsed(false);
// 线程安全的字符串缓冲类
StringBuffer stringBuffer = new StringBuffer();
// 构造参数 是Format子类里面的 自己特有的参数,传入就行
// 构造 小数部分的,所以开始 beginIndex()是从小数点 后面算的,  但是0是从整个格式化数字,第一个算起, 包括 之间用于分组的 " ,"
FieldPosition fieldPosition = new FieldPosition(NumberFormat.FRACTION_FIELD);
stringBuffer = numberFormat.format(1234.56789, stringBuffer, fieldPosition);
System.out.println(stringBuffer.toString());
// 小数部分, 所以 从 5 开始
System.out.println(fieldPosition.getBeginIndex() + "   " + fieldPosition.getEndIndex());
// 切割字符串
System.out.println(stringBuffer.toString().substring(fieldPosition.getBeginIndex()));

运行结果

在这里插入图片描述

DecimalFormat

DecimalFormat是NumberFormat十进制数字格式的具体子类 。
它具有多种功能,旨在解析和格式化任何语言环境中的数字,包括支持西方,阿拉伯语和印度语数字。它还支持不同类型的数字,包括整数(123),定点数(123.4),科学记数法(1.23E4),百分比(12%)和货币金额(123美元)。所有这些都可以本地化。

获取DecimalFormat实例

要获取特定区域设置的NumberFormat(包括默认语言环境),请致电NumberFormat的工厂方法之一,例如getInstance() 。
一般来说,不要直接调用DecimalFormat构造函数,因为NumberFormat工厂方法可能会返回DecimalFormat以外的子类。
如果您需要自定义格式对象,请执行以下操作:

NumberFormat f = NumberFormat.getInstance(loc);
if (f instanceof DecimalFormat) {
    ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true);
}

Pattern(模式)

A DecimalFormat包括图案和一组符号。 可以使用applyPattern()或间接使用API方法直接设置模式。
符号存储在一个DecimalFormatSymbols对象中。
当使用NumberFormat工厂方法时,模式和符号从本地化的ResourceBundle读取。

DecimalFormat作为NumberFormat的具体实现子类,最大的特点就是 可以使用 Pattern。来实现最大程度的对数据格式进行定制。
一个Pattern中的许多字符是按字面意思理解的;它们在解析期间匹配,在格式化期间输出不变,就是字符在Pattern中不影响最后的数字格式化另一方面,特殊字符代表其他字符、字符串或字符类。如果要以文字形式出现在前缀或后缀中,必须引用它们(除非另有说明)。

在这里插入图片描述

0 和 # 的区别

  1. 以“0”补位时

如果数字少了,就会补“0”,小数和整数都会补;
如果数字多了,就切掉,但只切小数的末尾,整数不能切;
同时被切掉的小数位会进行四舍五入处理。

  1. 以“#”补位时

如果数字少了,则不处理,不会补“0”,也不会补“#”;
如果数字多了,就切掉,但只切小数的末尾,整数不能切;
同时被切掉的小数位会进行四舍五入处理。

总结

  1. “0”:强制按格式对齐,“#” 最充足的情况下以这样的格式对齐;

  2. “#”:适用的场景是当小数位超过两位时,只显示两位,但只有一位或没有,则不需要补“0”;

  3. 整数位用多个 “#” 没有意义。

使用示例

import java.text.DecimalFormat;

public class DecimalFormatTest {
    public static void main(String[] args) {
        // 创建 DecimalFormat 格式化对象
        // 实例化DecimalFormat对象
        DecimalFormat df = new DecimalFormat();
        // 使用applyPattern方法设置格式化模板
        // #:代表数字,如果位上不存在,则不显示
        df.applyPattern("###,###,###");
        int num = 123456789;
        String str = df.format(num);
        System.out.println(num+"--"+ "###,###,###"+"--"+str);

        // 在数字后面加单位
        df.applyPattern("000000000.###kg");
        str = df.format(num);
        System.out.println(num+"--"+"000000000.###kg"+"--"+str);

        // 按照模板格式化数字,不存在的位以0显示
        df.applyPattern("0000000.0000");
        num = 12345678;
        str = df.format(num);
        System.out.println(num+"--"+"0000000.0000"+"--"+str);

        // 将数字转化为百分数
        double n = 0.1234;
        df.applyPattern("#.###%");
        str = df.format(n);
        System.out.println(n+"--"+"#.###%"+"--"+str);

        // 数字格式化为两位
        n = 1235467.5555;
        df.applyPattern("#####.##");
        str = df.format(n);
        System.out.println(n+"--"+"#####.##"+"--"+str);

        // 转化为千分形式
        n = 0.789;
        df.applyPattern("0.00\\u2030");
        str = df.format(n);
        System.out.println(n+"--"+"0.00\\u2030"+"--"+str);

        // 将数字进行分组操作
        DecimalFormat format=new DecimalFormat();
        format.setGroupingSize(2);
        String out=format.format(10022223);
        System.out.println("数字分组:"+out);
        // 设置是否分组
        format.setGroupingUsed(false);
    }
}

结果展示
在这里插入图片描述

通用格式

// 创建一个默认的通用格式
NumberFormat numberFormat = NumberFormat.getInstance();
DecimalFormat numberDecimalFormat;
// 捕捉异常,以防强制类型转换出错
try {
   //强制转换成DecimalFormat
   numberDecimalFormat = (DecimalFormat) numberFormat;
   // 保留小数点后面三位,不足的补零,前面整数部分 每隔四位 ,用 “,” 符合隔开
   numberDecimalFormat.applyPattern("#,####.000");
   //设置舍入模式 为DOWN,否则默认的是HALF_EVEN
   numberDecimalFormat.setRoundingMode(RoundingMode.DOWN);
   // 设置 要格式化的数 是正数的时候。前面加前缀
   numberDecimalFormat.setPositivePrefix("Prefix  ");
   System.out.println("正数前缀  "+numberDecimalFormat.format(123456.7891));
   // 设置 要格式化的数 是正数的时候。后面加后缀
   numberDecimalFormat.setPositiveSuffix("  Suffix");
   System.out.println("正数后缀  "+numberDecimalFormat.format(123456.7891));
   // 设置整数部分的最大位数
   numberDecimalFormat.setMaximumIntegerDigits(3);
   System.out.println("整数最大位数 "+numberDecimalFormat.format(123456.7891));
   // 设置整数部分最小位数
   numberDecimalFormat.setMinimumIntegerDigits(10);
   System.out.println("整数最小位数 "+numberDecimalFormat.format(123456.7891));
   // 设置小数部分的最大位数
   numberDecimalFormat.setMaximumFractionDigits(2);
   System.out.println("小数部分最大位数 "+numberDecimalFormat.format(123.4));
   // 设置小数部分的最小位数
   numberDecimalFormat.setMinimumFractionDigits(6);
   System.out.println("小数部分最小位数 "+numberDecimalFormat.format(123.4));
} catch (Exception e){
   e.printStackTrace();
}

参考博客:
Link
Link

感谢

加油

继续努力

以上是关于Java 详解数字格式化(NumberFormat&DecimalFormat)的主要内容,如果未能解决你的问题,请参考以下文章

《Java实战常用类》第11节:NumberFormat类和DecimalFormat类

java.text.Format及相关类详解

Java.格式化输出

Java 数字格式

修改 NumberFormat.getCurrencyInstance() 返回的 NumberFormat

DecimalFormat详解