美文网首页
小坑大错之DecimalFormat采坑日记

小坑大错之DecimalFormat采坑日记

作者: Swy2w | 来源:发表于2018-09-03 13:30 被阅读13次

引言

在最近的开发中,用到了DecimalFormat这个类来做精度控制的功能。比如想保留两位精度,代码如下:

        DecimalFormat decimalFormat = new DecimalFormat("0.##");
        decimalFormat.format(12345.2323)

        输出结果为:12345.23

掉坑与填坑

使用#和0的区别

对于使用数字"0"格式化,和使用“#”格式化在DecimalFormat中的区别在于:

  • "#" 表示有”有效“数字才显示。而使用数字 "0" 则表示在位数不足时或者"无效"时用"0"值补位。

这里的有效和无效指的是数学意义上的有效值。比如0010.2300,有效值为10.23,无效值为千位和百位的0,以及小数点第三位和第四位的0

看以下例子:

        DecimalFormat decimalFormat1 = new DecimalFormat("#.##");
        DecimalFormat decimalFormat2 = new DecimalFormat("0.00");
        System.out.println(decimalFormat1.format(45.2));
        System.out.println(decimalFormat1.format(45.20));
        System.out.println(decimalFormat2.format(45.2));
        System.out.println(decimalFormat2.format(45.20));

        System.out.println("******************整数部分测试********************");

        DecimalFormat decimalFormat3 = new DecimalFormat("####.00");
        DecimalFormat decimalFormat4 = new DecimalFormat("0000.00");
        System.out.println(decimalFormat3.format(0.20));
        System.out.println(decimalFormat3.format(10.20));
        System.out.println(decimalFormat4.format(0.20));
        System.out.println(decimalFormat4.format(10.20));
        
        输出为:
        ******************小数部分测试********************
        45.2
        45.2
        45.20
        45.20
        ******************整数部分测试********************
        .20
        10.20
        0000.20
        0010.20
使用除0和#以外的格式符号

对于某些特殊符号,比如“%”会对整体乘以100。或者有时候我们可能需要对格式化后的数据带上前缀或者后缀,比如如果说需求要求格式化的代码如下所示:

        DecimalFormat decimalFormat1 = new DecimalFormat("#.##%");
        DecimalFormat decimalFormat2 = new DecimalFormat("a0.00");
        DecimalFormat decimalFormat3 = new DecimalFormat("负数-0.0");
        DecimalFormat decimalFormat4 = new DecimalFormat("上午(0.0am0)");

对于这种情况(不要问我怎么有这种需求),会筛选除“0”和“#”进行格式化,并在整数前面加上前缀,小数后面带后缀,比如上面的输出结果如下所示:

        System.out.println(decimalFormat1.format(12.222));
        System.out.println(decimalFormat2.format(12.222));
        System.out.println(decimalFormat3.format(12.222));
        System.out.println(decimalFormat4.format(12.222));
        输出结果:
        1222.2%
        a12.22
        负数-12.2
        上午(12.22am)
格式化后转换成数值问题

这种问题分两种情况

  • 带分隔符的格式化后的数据转换问题
  • 语言环境格式化差异带来的数据转换问题

第一种情况比较有可预见性,比如以下代码:

        DecimalFormat decimalFormat = new DecimalFormat(",###.##");
        //报java.lang.NumberFormatException
        Double.valueOf(decimalFormat1.format(12345.2323));

原因是因为格式化的数据变成了“12,345.23”,所以会抛出NumberFormatException。这种情况一般情况下都能考虑到,但是第二种情况就有点坑爹了。看以下代码:

        DecimalFormat decimalFormat = new DecimalFormat("#.##");
        decimalFormat.format(12345.2323)

就是开头最简单的例子,在中文和英文环境会输出我们预计的结果“12345.23”。

但是!!,在譬如德语等环境下,会输出“12345,23”。原因是因为德语环境下的逗号和点号分隔符的作用是完全相反的。所以如果接下来我们使用了”Double.valueOf()“等转换操作,将会爆出NumberFormatException异常。通过查看DecimalFormat的构造方法:

    public DecimalFormat(String pattern) {
        // Always applyPattern after the symbols are set
        this.symbols = DecimalFormatSymbols.getInstance(Locale.getDefault(Locale.Category.FORMAT));
        applyPattern(pattern, false);
    }

默认是使用当前语言环境作为格式化的符号,因此我们可以手动设置格式化的符号,例如:

DecimalFormat.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.US));

但是强制使用某种语言环境下的格式化的符号是不可取的,程序中应该针对不同语言环境做不同处理。

相关文章

  • 小坑大错之DecimalFormat采坑日记

    引言 在最近的开发中,用到了DecimalFormat这个类来做精度控制的功能。比如想保留两位精度,代码如下: 掉...

  • 采坑日记

    采坑日记 在src/index.js中,对Model的引用,使用import 切换 HashRouter为 Bro...

  • Universal Link 前端部署采坑记

    Universal Link 前端部署采坑记 Universal Link 前端部署采坑记

  • 小程序采坑

    全局样式选择器*被禁用 上面的代码在编译的时候就会报错,因为小程序禁用了这类选择器。大胆猜测具体原因:这类作用范围...

  • 有的坑要早踩

    有的坑要早踩好处才大,因为年轻还可以有多次采坑的时间,总结经验知道为什么采坑,踩到了什么坑,而在我们年轻时,父母总...

  • NSURLSessionDownloadTask 断点下载

    采坑日记1-NSURLSessionDownloadTask下载断点,任务删除,手动杀进程,系统杀进程后继续下载 ...

  • 2019-08-01 疑难杂症之- hive踩坑

    很多时候,你以为你懂了,其实你并没有。采坑指南就是将踩过的坑记住。 1、hive 表新增字段时,采坑 2、hive...

  • Android开发史记一

    前言 转眼从事Android开发已经将近四年,突然发现曾经残留的采坑日记和注意点,在这里分享一下,帮助大家避免。之...

  • Flutter携程APP总结

    功能展示 首页实现 搜索页面实现 旅拍页面 DAO 采坑 启动屏 自定义Widget 打包 功能展示 DAO 采坑...

  • 小程序采坑之旅

    1. 微信小程序中使用腾讯地图 如果你的地图js插件是放在客户端不是部署在服务器的,比如放在小程序端,请把腾讯地图...

网友评论

      本文标题:小坑大错之DecimalFormat采坑日记

      本文链接:https://www.haomeiwen.com/subject/icsbwftx.html