Java 详解数字格式化(NumberFormat&DecimalFormat)
Posted ZSYL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 详解数字格式化(NumberFormat&DecimalFormat)相关的知识,希望对你有一定的参考价值。
NumberFormat&DecimalFormat
对于 DecimalFormat类的使用,学了之后,也放了很久,不经常用,忘得差不多了,最近比赛用到数据格式化,小数点保留指定位数,所以重新拾起来,复习一下。
前言
查看官方 API 发现:
Java对文字,数字的格式化,是有一个公共的父类的 Format。
NumberFormat和DecimalFormat都是它的子类关于数字的。
DateFormat和SimpleDateFormat也是它的子类关于文字的。
要特别注意的是 NumberFormat和DecimalFormat 是线程不安全的。 这意味你如果同时有多个线程操作一个format实例对象,会出现意想不到的结果。
NumberFormat
NumberFormat帮助您格式化和解析任何区域设置的数字。您的代码可以完全独立于小数点,千位分隔符的区域设置约定,甚至是使用的特定十进制数字,或者数字格式是否为十进制。
NumberFormat是所有数字格式的抽象基类。 该类提供格式化和解析数字的接口。
NumberFormat还提供了确定哪些区域设置具有数字格式以及它们的名称的方法。
NumberFormat可帮助您格式化和解析任何区域设置的数字。 您的代码可以完全独立于小数点,数千分隔符或甚至使用的特定十进制数字的区域设置约定,或者数字格式是否为偶数十进制。
获取NumberFormat实例
//创建 一个整数格式,地区用系统默认的 NumberFormat实例对象
NumberFormat integerNumber = NumberFormat.getIntegerInstance(Locale.getDefault());
- 使用getInstance或getNumberInstance获取正常的数字格式。
- 使用getIntegerInstance得到的整数格式。
- 使用getCurrencyInstance来获取货币数字格式。
- 使用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 和 # 的区别
- 以“0”补位时:
如果数字少了,就会补“0”,小数和整数都会补;
如果数字多了,就切掉,但只切小数的末尾,整数不能切;
同时被切掉的小数位会进行四舍五入处理。
- 以“#”补位时:
如果数字少了,则不处理,不会补“0”,也不会补“#”;
如果数字多了,就切掉,但只切小数的末尾,整数不能切;
同时被切掉的小数位会进行四舍五入处理。
总结:
-
“0”:强制按格式对齐,“#” 最充足的情况下以这样的格式对齐;
-
“#”:适用的场景是当小数位超过两位时,只显示两位,但只有一位或没有,则不需要补“0”;
-
整数位用多个 “#” 没有意义。
使用示例
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();
}
感谢
加油
淦
继续努力
以上是关于Java 详解数字格式化(NumberFormat&DecimalFormat)的主要内容,如果未能解决你的问题,请参考以下文章
《Java实战常用类》第11节:NumberFormat类和DecimalFormat类