当前位置:

首页 > 编程开发 > java %0d,我如何使java.text.NumberFormat格式0.0d为“0”而不是“+0”?

java %0d,我如何使java.text.NumberFormat格式0.0d为“0”而不是“+0”?

针对Java数值格式化中零值不显示正号的需求,采用ChoiceFormat与DecimalFormat组合:ChoiceFormat将0映射为空、正数映射为“+”,DecimalFormat处理小数位与负号,实现零显示“0”、正数带“+”、负数带“-”。

在Ja va的数值格式化中,有时会遇到一个看似简单却很棘手的需求:既要显示正负号,又希望零值不带符号,直接显示为“0”。比如:-123.45 → “-123.45”,123.45 → “+123.45”,而0.0则要输出为“0”。

如果直接用DecimalFormat的setPositivePrefix("+"),你会发现0也会被格式化为“+0”——这显然不是我们想要的。那么,如何优雅地解决这个问题?

解决方案

这里可以借助ChoiceFormat来动态选择前缀。思路是:当数值为0时,不加任何前缀;当数值大于0时,加上“+”;负数则沿用默认的“-”。下面是一个完整的实现示例:

import static org.junit.Assert.assertEquals;
import ja va.text.ChoiceFormat;
import ja va.text.DecimalFormat;
import ja va.text.FieldPosition;
import ja va.text.NumberFormat;
import ja va.text.ParsePosition;
import org.junit.Test;

public class NumberFormatTest {
    @Test
    public void testNumberFormat() {
        NumberFormat nf = new MyNumberFormat();
        assertEquals("-1234.4", nf.format(-1234.4));
        assertEquals("0.0", nf.format(0));
        assertEquals("+0.3", nf.format(0.3));
        assertEquals("+12.0", nf.format(12));
    }
}

class MyNumberFormat extends NumberFormat {
    private DecimalFormat df = new DecimalFormat("0.0#");
    private ChoiceFormat cf = new ChoiceFormat(
        new double[] { 0.0, ChoiceFormat.nextDouble(0.0) },
        new String[] { "", "+" });

    @Override
    public StringBuffer format(double number, StringBuffer toAppendTo,
            FieldPosition pos) {
        return toAppendTo.append(cf.format(number)).append(df.format(number));
    }

    @Override
    public StringBuffer format(long number, StringBuffer toAppendTo,
            FieldPosition pos) {
        return toAppendTo.append(cf.format(number)).append(df.format(number));
    }

    @Override
    public Number parse(String source, ParsePosition parsePosition) {
        throw new UnsupportedOperationException();
    }
}

原理说明

DecimalFormat的模式字符串实际上包含正负两个子模式,负子模式是可选的。如果只写"0.0#",等价于"0.0#;-0.0#",也就是说对负数会自动加上“-”。所以直接使用DecimalFormat,是无法区分“0”和“正数”的——它们都会共用正子模式,而正子模式默认没有“+”。

那么,如何给正数加上“+”?答案是利用ChoiceFormat来做一个分段映射:

  • 当数值在 [0.0, ChoiceFormat.nextDouble(0.0)) 区间时,对应空字符串 ""。细心的读者会注意到,ChoiceFormat.nextDouble(0.0) 是大于0的最小浮点数,所以这个区间实际上只包含0.0本身。
  • 当数值大于等于 ChoiceFormat.nextDouble(0.0) 时,对应 "+"。这就覆盖了所有正数。
  • 负数呢?交给DecimalFormat自带的负子模式处理就好,ChoiceFormat对负数会返回空字符串(因为负无穷到0不在上述两个区间内,默认取第一个或最后一个索引),不会干扰负号。

换句话说,ChoiceFormat负责决定是否加上“+”前缀,而DecimalFormat负责处理数值的小数位数和负号。两者组合,正好实现了“零无符号、正数带+、负数带-”的效果。

如果对ChoiceFormat的边界行为有疑问,可以查阅文档:它的限制数组必须升序排列,未命中时会自动取最接近的边界。这里用ChoiceFormat.nextDouble(0.0)可以精确区分0与正数,是一个非常巧妙的技巧。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
作者最新文章
编程开发 Java
相关文章 更多
大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景
大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景

针对大数据工程场景,系统对比Java、Scala与Python在执行性能、生态结合、开发效率和维护成本上的核心差异,给出清晰的架构选型依据与落地方案。

Java抽象方法修饰符限制:为何不能用private或static
Java抽象方法修饰符限制:为何不能用private或static

深入剖析Java中抽象方法为何严禁使用private和static修饰符。从面向对象契约规范、方法继承重写、JVM动态绑定(invokevirtual)与静态解析(invokestatic)等底层机制展开详细推导,结合编译报错示例与全景对比,彻底理清修饰符限制背后的设计逻辑。

Java变量声明与初始化:局部、成员及静态变量的定义语法
Java变量声明与初始化:局部、成员及静态变量的定义语法

系统解析Java局部变量、成员变量与静态变量的定义语法、声明与初始化机制、生命周期及JVM内存驻留规则,结合图解与代码示例分析常见编译错误与认知误区。

Java子类未实现抽象方法编译错误修复指南
Java子类未实现抽象方法编译错误修复指南

针对Java开发中常见的“子类未实现抽象方法”编译错误,深入分析报错原因,提供重写实现、声明抽象子类两种标准修复路径,并总结参数签名、访问修饰符等典型避坑要点。

junit怎么用零基础完成第一个单元测试教程
junit怎么用零基础完成第一个单元测试教程

适合初学者的JUnit入门指南,详解如何配置环境、编写首个测试用例、使用断言验证结果,并分析单元测试的适用场景与例外情况。

Java发送post请求发送json数据的实现方法与代码示例
Java发送post请求发送json数据的实现方法与代码示例

深入解析Java发送JSON格式POST请求的实现机制,对比原生API与第三方库的代码差异,提供可复制的代码示例,并探讨超时设置、编码处理及微服务场景下的例外情况。

百度官网入口最新版 百度搜索网页版直达
百度官网入口最新版 百度搜索网页版直达

百度官方在线入口最新版网页版直达官网是https://www.baidu.com/,界面简洁无干扰、多端同步体验一致、内容聚合维度丰富、语音与图像识别稳定、隐私控制机制可见。

谷歌浏览器Mac版入口
谷歌浏览器Mac版入口

谷歌浏览器Mac版官方安装指南 谷歌浏览器Mac版官方安装入口是https://www.google.com/chrome/,需macOS 12+系统、500MB空间,下载.dmg后拖入应用程序安装,支持多设备同步、性能优化与隐私保护功能。 苹果电脑Chrome的安装入口究竟在哪里?这个问题最近可是

Chrome浏览器JS脚本不运行怎么办
Chrome浏览器JS脚本不运行怎么办

Chrome中JavaScript未执行需依次检查:一、移除站点级禁用并添加允许域名;二、开启全局JavaScript开关;三、禁用干扰扩展;四、在开发者工具中启用JavaScript;五、重置内容设置为默认。 有时在Chrome里打开网页,会发现交互按钮点了没反应,数据加载不出来,页面仿佛“静止”

IE浏览器怀旧版在线网址
IE浏览器怀旧版在线网址

IE浏览器怀旧版在线网址:一次精准的技术时光回溯 最近,不少老用户和怀旧爱好者在反复搜索一个问题:那个经典的Internet Explorer,如今还能在哪里原汁原味地体验到?答案指向一个特定的地址:https://ie.microsoft.com/legacy/。 这个网站远不止是一个简单的“皮肤

查看更多
精品专题 更多
装机必备
装机必备

正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

Windows
Windows

正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

PDF教程
PDF教程

正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

Mac软件 更多
AirBuddy 3 macOS版
AirBuddy 3 macOS版
macOS

AirBuddy 3 是面向 macOS 的蓝牙外设增强工具,可集中查看 AirPods、Beats 与苹果设备电量,提供快速连接、播放控制、电量提醒、桌面小组件和多台 Mac 外设接力等功能。

AirServer macOS版
AirServer macOS版
macOS

AirServer macOS版可把 Mac 转换为无线投屏接收端,通过 AirPlay 或 Google Cast 接收手机、平板和电脑画面,并支持多设备同时连接、高清镜像及会话录制,适合家庭娱乐、课堂教学、会议演示和应用展示。

AnyDesk macOS版
AnyDesk macOS版
macOS

AnyDesk macOS版是一款适用于远程办公、设备维护和客户支持的远程桌面工具,可连接并操作异地计算机,支持文件传输、无人值守访问、会话权限控制及跨平台协作。

WINDOWS 更多
Fuzor Windows版
Fuzor Windows版
Windows

Fuzor Windows版是一套面向建筑、工程与施工团队的BIM/VDC平台,可汇集多来源模型和进度数据,完成实时可视化、4D施工推演、场地物流规划、问题检查、成果演示及团队协同。

Gety Windows版
Gety Windows版
Windows

Gety Windows版是一款本地AI文件搜索工具,可索引电脑中的文档和图片,通过全文搜索、语义检索与OCR快速定位内容,并提供原版式预览、筛选和AI工具连接功能。

iMazing Windows版
iMazing Windows版
Windows

iMazing Windows版是一款面向iPhone、iPad和iPod用户的本地设备管理工具,可在电脑上完成多版本备份、照片与音乐传输、信息导出、应用数据管理以及新旧设备迁移。