JavaRush /Java 博客 /Random-ZH /在 Java 中格式化数字的输出

在 Java 中格式化数字的输出

已在 Random-ZH 群组中发布
大家好!通常我们的方法带有需要以某种特殊格式显示的数字。这看起来是一件小事,但是你会如何实现这个任务呢? 在 Java 中格式化数字的输出 - 1今天我们邀请您思考一下这个问题。首先,为了深入了解 Java 中的数字格式化,让我们记住String类的format方法: public static String format(String format, Object... args) -使用剩余的args参数返回从格式字符串格式化的字符串。只是一个例子:
String str = String.format("Hi - %s! How are you %s?", "Sasha", "At work");
System.out.println(str);
结果,我们将在控制台中得到输出:
你好萨莎!工作进展如何?

printf 和 format 方法

String.format()不是格式化字符串的唯一方法。它的类似物是System.out.printf()System.out.format();。因此,我们可以将之前的代码替换为:
System.out.printf("Hi - %s! How are you %s?", "Sasha", "At work");
或者
System.out.format("Hi - %s! How are you %s?", "Sasha", "At work");
控制台中的输出将保持不变。唯一的区别是这些方法会立即在控制台中显示值,这与String.format()不同。但我更喜欢String.format(),因为我们并不总是需要在控制台中显示结果,所以我们将进一步使用这个方法。让我们回到我们的例子。我们看到了什么?事实上,在有字符- %s的地方,插入了行- “Sasha”“at work”。这对我们的发展有何帮助?想象一下,您有一个很大的模板文本,但在某些地方您需要插入可能不同并作为来自外部的参数的值。这就是这种格式可以派上用场的地方。格式说明符以百分号 % 开头,以指示要格式化的参数类型的字符结尾。而且,正如您可能了解的那样,%s用于插入对象 - 字符串。但是,如果我们尝试将例如双精度数插入到注册字符串对象的位置:
String str = String.format("Hi - %s! How are you %s?", 55.6, "At work");
这也行。double将被转换为字符串,我们将得到:
你好 - 55.6!工作进展如何?
Java中除了字符串和浮点数之外,还有其他类型吧?那么让我们看一下整个武器库:
要格式化的值的类型 例子
%s 任何将被转换为字符串的类型
String.format("Hi %s!","world")
结果:
你好世界!
%b 将转换为boolean 的任何类型: true - 如果值不为 null, false - 如果为 null
String.format("Hi %b!",null)
结果:
你好假
%H 您可以传递任何对象,该对象将从hashCode()方法转换为十六进制值字符串
String.format("Hi %h!","world")
结果:
你好106c44!
%C 用于指定 Unicode 字符 ( char )
String.format("Hello m%cr!",'And')
结果:
你好世界!
%d 指定一个整数(int.byte、short、int、long、BigInteger
String.format("I'm already %d!",20)
结果:
我已经20岁了!
%F 用于指定浮点数
String.format("PI is - %f!", 3.14159)
结果:
PI 号是 - 3.141590!
%e 科学计数法中的浮点数
String.format("PI is - %e!", 3.14159);
结果:
PI 号是 - 3.141590e+00!
%A 浮点数将以十六进制表示
String.format("PI is - %a!", 3.14159)
结果:
PI 号是 - 0x1.921f9f01b866ep1!
%X 传递一个整数(int.byte、short、int、long、BigInteger),格式化结果将是ASCII表中给定数字的字符
String.format("I'm already %x!",25)
结果:
我已经19岁了!
%o 接受整数(int.byte、short、int、long、BigInteger)并将其表示为八进制数
String.format("I already %o!",25);
结果:
我已经31岁了!
%t 日期和时间转换的前缀。格式化需要额外的标志
String.format("Today is %tA",new Date())
结果:
今天是星期六
%n 特定于平台的行分隔符。模拟\n
String.format("Hello %n Hello")
结果:
嗨嗨
让我们为double使用更合适的格式 :
String str = String.format("The distance from Kyiv to Odessa is %f. Not so short, is it?", 475.4d);
System.out.println(str);
控制台输出:
基辅 到 敖德萨 的距离是 475.400000。没那么少吧?
您可能已经意识到,%f对于浮点数来说是更合适的说明符,其中包括Java 中的doublefloat等数据类型。使用这个说明符,我们可以格式化浮点数:
String str = String.format("The distance from Kyiv to Odessa is %.2f. Not so short, is it?", 475.4d);
.2插入此说明符会将小数位数截断为两位,从而得到输出:
基辅 到 敖德萨 的距离是 475.40。没那么少吧?
.2并不是对说明符的唯一调整。这些子集的组合称为指令指令的在 Java 中格式化数字的输出 - 2一般形式如下:
%[argument_index][flags][width][. precision]类型说明符
现在让我们按顺序破译一切:
  • [argument_index]是一个整数,指示参数列表中的位置。例如,第一个参数的链接是 $1,第二个参数的链接是 $2,等等。如果未指定位置,则参数的顺序必须与格式字符串中引用的顺序相同。
  • [flags]是用于格式化的特殊字符。例如:
    • +标志,指示如果数值为正,则必须包含 + 符号
    • -表示结果左对齐
    • ,设置整数的千位分隔符
  • [width]是一个十进制正整数,指定将输出的最小字符数。如果这个数字前面有0,那么缺失的字符将用0填充,如果没有0,则用空格填充。
  • [.accuracy]是一个非负整数,前面有一个点。通常用于限制字符数。具体行为取决于说明符的具体类型。
我还想指出,说明中的所有上述元素都是可选的,没有它们一切都会工作。作为使用子集的示例,假设我们需要数字 Pi 的特定输出:
String str = String.format("%1$+09.5f", 3.1415926535897);
System.out.print(str);
相应地,控制台中的输出:
+03.14159
看起来很容易,对吧?但是当谈到格式化数字时,你不能忽视DecimalFormat。让我们弄清楚这意味着什么。

十进制格式

DecimalFormat是一个用于格式化 Java 中任何数字的类,无论是整数还是浮点数。创建DecimalFormat对象后,您可以直接在构造函数中指定用于格式化传入数字的模板。这就是我们使用DecimalFormat 的示例:
DecimalFormat dF = new DecimalFormat( "#.###" );
double value = 72.224463;
System.out.print(dF.format(value));
控制台输出:
72,224
#.### 行是一种模式,指示我们将传递的值格式化为小数点后 3 位。还有哪些其他符号可用于图案?这里是其中的一些:
  • # — 数字,省略前导零;
  • 0 — 始终显示该数字,即使该数字的位数较少(在这种情况下,显示 0);
  • ——小数点分隔符;
  • , — 分隔符分组符号(例如,千位分隔符);
  • ; — 分隔格式;
  • -——标记负数的前缀;
  • % - 乘以 100 并将数字显示为百分比;
  • — 乘以 1000,并显示以 ppm 为单位的数字;
  • E - 分隔科学记数法的尾数和指数。
让我们看几个例子:
System.out.println(new DecimalFormat( "###,###.##" ).format(74554542.224463));
控制台输出:
74,554,542.22
System.out.println(new DecimalFormat( "%###.##" ).format(0.723456));
控制台输出:
%72.35
System.out.println(new DecimalFormat( "000.###" ).format(42.224463));
控制台输出:
042.224
不必每次都创建新的DecimalFormat对象来定义新模板。使用其applyPatternapplyLocalizedPattern方法就足够了:
DecimalFormat dF = new DecimalFormat("###.###");
dF.applyPattern("000000.000");
dF.applyLocalizedPattern("#,#00.0#");
当我们谈论格式化浮点数时,我们对舍入非常感兴趣,不是吗?因此,当修剪小数位数超出指定模式的数字时,如果最后修剪的数字大于 5,DecimalFormat会将数字向上舍入。如果最后修剪的数字是 5,该怎么办?事实上,在这种情况下,这个数字恰好位于最接近的整数之间的中间。在 Java 中格式化数字的输出 - 3在这种情况下,会考虑之前的数字。如果前一个数字是偶数,则进行舍入:
DecimalFormat dF = new DecimalFormat("##.###");
String result = dF.format(56.4595);
System.out.println((result));
控制台输出:
56,459
如果是奇数,则不执行:
DecimalFormat dF = new DecimalFormat("##.###");
String str = dF.format(56.4595);
System.out.println((str));
控制台输出:
56,459
使用String.format()DecimalFormat.format() 格式化浮点数的区别在于,在第一种情况下,即使没有小数部分,也会有尾随零。例如:
String firstStr = String.format("%.4f", 9.00001273);
System.out.println((firstStr));
控制台输出:
9.0000
DecimalFormat decimalFormat = new DecimalFormat("#.####");
String secondStr = decimalFormat.format(9.00001273);
System.out.println((secondStr));
控制台输出:
9
如您所见,当以四位小数的精度格式化数字9.00001273时, String类的format()方法将输出值9.0000,而DecimalFormat的类似format()方法将输出9

BigDecimal 和 BigInteger

既然我们已经接触到了Java中的舍入数字的话题,那么我们就来谈谈如何使用BigDecimal类来进行这样的操作。这个类的重点是处理非常大的数字:对于它来说,最大双精度浮点值太小。该类有许多不同的浮点舍入设置,以及许多算术运算方法。它有一个类似的类,但专注于处理大整数 - BigInteger。您可以在本文中阅读有关BigDecimalBigInteger的更多信息。

设置日期和时间格式

上面只提到使用String类的format()还可以格式化时间和日期。好吧,让我们看看它是如何完成的。首先,我们想提醒您,%t格式说明符用于日期。其次,在格式化模板时,每个日期格式说明符都需要附加格式化标志。以下是日期可能的格式标志:在 Java 中格式化数字的输出 - 4
旗帜 描述
%tB 月份的全名,例如,一月、二月等。
%tb 月份的缩写名称,例如 Jan、Feb 等。
%tA 一周中某一天的全名,例如星期日、星期一
%ta 星期几的缩写名称,例如 Sun、Mon 等。
%tY 4 位数字格式的年份,例如 0000 到 9999
%ty 两位数格式的年份,例如从 00 到 99
%Tm值 月份格式以零开头,例如 01 到 12
%tc 日期和时间,格式为 %ta %tb %td %tT %tZ %tY,例如 Mon Feb 17 03:56:12 PST 2020
%tD %tm/%td/%ty 格式的日期
%td 两位数格式的月份中的第几天,例如 01 到 31
%te 月份中的第几天,格式不带前导 0,例如从 1 到 31
%tT 24 小时格式的时间,例如 %tH:%tM:%tS
%tH 24 小时格式的一天中的小时,从 00 到 23
%tI 12 小时格式的一天中的小时,例如 01 到 12
%Tm值 小时中的分钟格式采用前导零,例如 00 到 59
%tS 一分钟中的秒数,由两位数字组成,例如从 00 到 59
%tZ 时区缩写,例如 PST、UTC 等。
这是可能的日期格式标志的简短列表 - 其中有很多,适合各种口味。可以在此链接中找到它们和可能的说明符的完整列表。让我们看看如何使用它。这次我们不使用String.format(),而是立即使用System.out.printf()

实施例1

此外,我们将通过将结果语言作为第一个参数传递给该方法来设置它:
Date date = new Date();
System.out.printf(Locale.ENGLISH,"%tB %te, %tY",date,date,date);
控制台输出:
2020 年 10 月 11 日
如果不指定语言,将使用默认语言(例如,我有俄语)。

实施例2

让我们显示更完整的日期:
Date date = new Date();
System.out.printf("%td %tB %tY of %n%tH:%tM:%tS",date,date,date,date,date,date,date);
以及控制台中的输出:
2020 年 10 月 11 日 13:43:22
多次传递同一个 Date 对象作为参数...看起来不太好,不是吗?让我们使用$内部子集来指定我们要使用的参数:
System.out.printf("%1$td %1$tB %1$tY of year %n%1$tH:%1$tM:%1$tS",date);
我们控制台中的输出不会改变。还有其他同样有趣的日期格式设置方法。您可以在本材料中了解它们以及有关 Java 时间和日期的更多信息。今天就到这里,感谢大家的关注!在 Java 中格式化数字的输出 - 5
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION