DecimalFormat - 格式化数据

开发过程中,通常会遇到一个问题:我们需要将一个数值转换为格式化的数值,比:3.145678保留两位有效数字,这时候我们该用什么方法来转换呢?
这篇笔记,将教会我们如何将Stringdoublefloat格式化为我们所需要的格式(比如:保留两位小数),而我们要用到的对象就是:DecimalFormat


1、DecimalFormat的介绍

  • 全路径名:java.text.DecimalFormat
  • JavaSE官方文档的描述:

DecimalFormat 是 NumberFormat 的一个具体子类,用于格式化十进制数字。该类设计有各种功能,使其能够解析和格式化任意语言环境中的数,包括对西方语言、阿拉伯语和印度语数字的支持。它还支持不同类型的数,包括整数 (123)、定点数 (123.4)、科学记数法表示的数 (1.23E4)、百分数 (12%) 和金额 ($123)。所有这些内容都可以本地化。

  • 舍入
    DecimalFormat 提供 RoundingMode 中定义的舍入模式进行格式化。默认情况下,它使用 RoundingMode.HALF_EVEN。
  • 以上是JavaSE官方文档的一些描述,下面我们需要进行一些自己的使用总结。

2、使用方法

2.1、占位符的使用

我们要实现格式化数据,需要使用到DecimalFormat的其中一个构造方法:

public DecimalFormat(String pattern)

构造参数pattern就是用来格式化的:一个非本地化的模式字符串。
0#都是常用的占位符,但是他们俩还有些区别。
下面我们举几个例子看看pattern的具体使用,以及0#的区别。

2.1.1 - 0占位符的使用

占位符比实际数字多
new DecimalFormat("00.00").format(3.14567);//结果:03.15
new DecimalFormat("0.000").format(3.14);//结果:3.140
new DecimalFormat("00.000").format(3.14);//结果:03.140
占位符比实际数字少
new DecimalFormat("00.00").format(13.14567);//结果:13.15
new DecimalFormat("0.000").format(13.14567);//结果:13.146
new DecimalFormat("0.00").format(13.14567);//结果:13.15
总结

使用0占位符的时候:
1、 比实际数字的位数多,不足的地方用0补上。
2、 比实际数字的位数少:整数部分不改动,小数部分,四舍五入(其实并不是四舍五入,而是默认的RoundingMode.HALF_EVEN方式,下面会讲到DecimalFormat的舍入方式)。

2.1.2 - #占位符的使用

占位符比实际数字多
new DecimalFormat("##.##").format(3.14567);//结果:3.15
new DecimalFormat("#.###").format(3.14);//结果:3.14
new DecimalFormat("##.###").format(3.14);//结果:3.14
占位符比实际数字少
new DecimalFormat("#.###").format(13.145678);//结果:13.146
new DecimalFormat("##.##").format(13.14567);//结果:13.15
new DecimalFormat("#.##").format(13.14567);//结果:13.15
总结

使用#占位符的时候:
1、 比实际数字的位数多,不变。
2、 比实际数字的位数少:整数部分不改动,小数部分,四舍五入(其实并不是四舍五入,而是默认的RoundingMode.HALF_EVEN方式,下面会讲到DecimalFormat的舍入方式)。

2.1.3 占位符使用总结

通过上面的例子,可以看到0和#占位符的区别,在实际使用的时候,可以根据不同需来选择占位符。
比如:
1、格式化数字,保留两位小数,不足的小数部分用0代替,这时候,我们就可以使用:"0.00"
2、格式化数字,只保留有效数字,最多保留两位小数,这时候,我们就可以使用:"#.##"

2.2 DecimalFormat的格式化方式(舍入方式)

在以上的几个例子,我们可以发现,当要格式化的数字超过占位符的时候,格式化的结果会进行四舍五入。这并不是按照四舍五入的方式舍入的,而是因为没有指定格式化的RoundingMode,而默认使用了RoundingMode.HALF_EVEN方式。
关于RoundingMode,这里就不做介绍了,可以参照另一篇笔记BigDecimal - 用于加、减、乘、除计算的工具类
,里面对RoundingMode进行了详细的介绍。

使用方式

下面举两个例子,指定舍入方式的格式化。

DecimalFormat format = new DecimalFormat("#.##");
//指定舍入方式为:RoundingMode.DOWN,直接舍去格式化以外的部分
format.setRoundingMode(RoundingMode.DOWN);
String formatDown = format.format(13.14567);//结果:13.14
//指定舍入方式为:RoundingMode.HALF_UP,四舍五入
format.setRoundingMode(RoundingMode.HALF_UP);
String formatHalfUp = format.format(13.14567);//结果:13.15

总结

关于DecimalFormat 的舍入方式,可以参考以上的例子,根据需求的不同,使用对应的RoundingMode

3、封装

BigDecimal - 用于加、减、乘、除计算的工具类这篇笔记中,我们说过,要用String类型进行加、减、乘、除运算。所以,我们接受服务器返回的数据都是用String类型接收的,这时候我们用DecimalFormat 如何格式化String类型的数据呢?
下面是个例子来实现String类型的格式化,将String类型的数据,格式化为只保留有效数字,最多保留两位小数,采用截取方式的方法(这个方法返回的是double,至于返回String、float、int都是可以的)。

    /**
     * @param str 需要格式化的字符串
     * @return 格式化后的double型数值
     */
    public static double stringToDouble(String str) {
        if (TextUtils.isEmpty(str)) {
            return 0;
        }
        DecimalFormat format = new DecimalFormat("#.##");
        //提供 RoundingMode 中定义的舍入模式进行格式化。默认情况下,它使用 RoundingMode.HALF_EVEN。
        format.setRoundingMode(RoundingMode.DOWN);
        //使用BigDecimal对象来将String类型转换为DecimalFormat可以格式化的类型。
        String formatStr = format.format(new BigDecimal(str));
        //将格式化后的类型,转换为double类型(当然,也可以转换为float或int,视需求而定)。
        BigDecimal bigDecimal = new BigDecimal(formatStr);
        return bigDecimal.doubleValue();
    }

4、总结

以上是DecimalFormat的一些基础使用,在实际开发过程中:
1、根据不同需求,来判断使用哪种占位符:0#
2、根据不同需求,来判断使用哪种舍入方式:RoundingMode.DOWNRoundingMode.HALF_UP等等。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,837评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,551评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,417评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,448评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,524评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,554评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,569评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,316评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,766评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,077评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,240评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,912评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,560评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,176评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,425评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,114评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,114评论 2 352

推荐阅读更多精彩内容