今天复习了下jdk的api。发现了一个数字格式的好工具。
以前做数字格式化都自己莽搓搓的去写。浪费了大量的时间。
记录下来,免得下次搞忘了。
使用类:
java.text
类 NumberFormat
java.lang.Object
java.text.Format
java.text.NumberFormat
- 所有已实现的接口:
- Serializable, Cloneable
- 直接已知子类:
- ChoiceFormat, DecimalFormat
NumberFormat 是所有数值格式的抽象基类。
使用 getInstance
或 getNumberInstance
来获取常规数值格式。使用 getIntegerInstance
来获取整数数值格式。使用 getCurrencyInstance
来获取货币数值格式。使用 getPercentInstance
来获取显示百分比的格式。使用此格式,小数 0.53 将显示为 53%。
使用 setMinimumFractionDigits
之类的方法还可以控制数值的显示。如果想对格式化和解析进行更多的控制(或者给予用户更多的控制),可以尝试将从工厂方法获取的 NumberFormat
强制转换为 DecimalFormat
。这适用于大多数语言环境;只是要记住将其放入一个 try
代码块中,以防遇到特殊情况。
使用NumberFormat 类测试下小数 0.53 将显示为 53%:
double d = 0.53d;
NumberFormat numberFormat = NumberFormat.getPercentInstance();
System.out.println(numberFormat.format(d));
模式
DecimalFormat
模式具有下列语法:
模式: 正数模式 正数模式;负数模式 正数模式: 前缀opt 数字后缀opt 负数模式: 前缀opt 数字后缀opt 前缀: 除 \uFFFE、\uFFFF 和特殊字符以外的所有 Unicode 字符 后缀: 除 \uFFFE、\uFFFF 和特殊字符以外的所有 Unicode 字符 数字: 整数指数opt 整数。小数指数opt 整数: 最小整数 # # 整数 # , 整数 最小整数: 0 0 最小整数 0 , 最小整数 小数: 最小小数opt 可选小数opt 最小小数: 0 最小小数opt 可选小数: # 可选小数opt 指数: E 最小指数 最小指数: 0 最小指数opt
DecimalFormat
模式包含正数和负数子模式,例如 "#,##0.00;(#,##0.00)"
。每个子模式都有前缀、数字部分和后缀。负数子模式是可选的;如果存在,则将用已本地化的减号(在多数语言环境中是 '-'
)作为前缀的正数子模式用作负数子模式。也就是说,单独的 "0.00"
等效于 "0.00;-0.00"
。如果存在显式的负数子模式,则它仅指定负数前缀和后缀;数字位数、最小位数,其他特征都与正数模式相同。这意味着 "#,##0.0#;(#)"
的行为与 "#,##0.0#;(#,##0.0#)"
完全相同。
特殊模式字符
模式中的很多字符都是按字面解释的;在解析期间对其进行匹配,在格式化期间则不经改变地输出。另一方面,特殊字符代表了其他字符、字符串或字符类。如果要将其作为字面量出现在前缀或后缀中,那么除非另行说明,否则必须对其加引号。
下列字符用在非本地化的模式中。已本地化的模式使用从此格式器的 DecimalFormatSymbols
对象中获得的相应字符,这些字符已失去其特殊状态。两种例外是货币符号和引号,不将其本地化。
符号 位置 本地化? 含义 0
数字 是 阿拉伯数字 #
数字字 是 阿拉伯数字,如果不存在则显示为 0 .
数字 是 小数分隔符或货币小数分隔符 -
数字 是 减号 ,
数字 是 分组分隔符 E
数字 是 分隔科学计数法中的尾数和指数。在前缀或后缀中无需加引号。 ;
子模式边界 是 分隔正数和负数子模式 %
前缀或后缀 是 乘以 100 并显示为百分数 \u2030
前缀或后缀 是 乘以 1000 并显示为千分数 ¤
(\u00A4
)前缀或后缀 否 货币记号,由货币符号替换。如果两个同时出现,则用国际货币符号替换。如果出现在某个模式中,则使用货币小数分隔符,而不使用小数分隔符。 '
前缀或后缀 否 用于在前缀或或后缀中为特殊字符加引号,例如
"'#'#"
将 123 格式化为
"#123"
。要创建单引号本身,请连续使用两个单引号:"# o''clock"
。
以前做评分功能的时候,功能要求只用保存两位小数点。那时候就用String做格式,判断数字里面是否有小数点,小数位数多少位,大于2位就把2位以后的删除掉。感觉挺麻烦的。
来看看DecimalFormat:
// 声明一个测试数据
double num = 10000124d;
// 当数字为整数,没有小数点 结果为: 10,000,124 元
//DecimalFormat format = new DecimalFormat("###,###,###.## 元");
// 默认最后有两个小数点,小数位数不够用0代替 结果为: 10,000,124.00 元
DecimalFormat format = new DecimalFormat("###,###,###.00 元");
System.out.println(format.format(num));
在看看ChoiceFormat的使用:
ChoiceFormat
允许将格式应用到某个范围的数。它通常用于在 MessageFormat
中处理复数。使用按升序排列的 double 列表指定 choice,列表中每一项都指定一个到下一项的半开区间:
当且仅当 limit[j] <= X < limit[j+1] 时,X 匹配 j
如果不匹配,则根据数 (X) 的是太小还是太大,选择使用第一个或最后一个索引。如果 limit 数组不按升序排列,则格式化的结果将不正确。ChoiceFormat 还接受 \u221E
(等同于无穷大 (INF))。
列子:
double[] limits = {0,1,2,3,4,5,6};
String[] dayOfWeekNames = {"星期天","星期一","星期二","星期三",
"星期四",
"星期五",
"星期六"};
ChoiceFormat form = new ChoiceFormat(limits, dayOfWeekNames);
ParsePosition status = new ParsePosition(0);
for (double i = 0.0; i <= 6.0; ++i) {
status.setIndex(0);
System.out.println(i + " -> " +
// 将数字表示的星期转换为中文表示的星期
form.format(i) + " -> "
// 数据反解析,将星期转换为数字
+ form.parse(form.format(i),status));
}