Android 系列 6.27格式化数字

时间:2021-02-04 19:15:00
6.27格式化数字
问题
您需要格式化数字,因为Double.toString()和朋友的默认格式不能给您足够的控制结果的显示方式。

使用String.format()或NumberFormat子类之一。
讨论
printf()函数在20世纪70年代被包括在C编程语言中,并且它已经用于许多其他语言,包括Java。这里是一个简单的printf示例在Java SE:
System.out.printf(“Hello%s at%s%n”,userName,time);
前面的例子可以打印如下:
Hello Robin at Wed Jun 16 08:38:46 EDT 2010
由于我们没有在Android中使用System.out,你会很高兴地注意到,你可以得到相同的字符串将被打印,放入一个视图,使用:
String msg = String.format(“Hello%s at%s%n”,userName,time);
如果你以前没有见过printf,第一个参数显然是格式代码字符串,任何数量的其他参数(userName和time)都是要格式化的值。格式代码以百分号(%)开头,并且至少有一个“类型”代码;常用类型代码如表6-1所示。
表6-1。一些常见的格式代码
Android 系列 6.27格式化数字

默认的日期格式很丑,所以我们经常需要展开它。 printf格式化功能实际上位于java.util.Formatter类中,应该参考其格式化语言的完整细节。
与你可能使用的其他语言的printf不同,所有这些格式化例程可以允许你通过参数的数字来引用参数,通过在%lead-in之后但在格式化代码之前加一个数字加一个美元符号;例如,%2 $ 3.1f表示将第二个参数格式化为具有三个字符和小数位后一位的十进制数。此编号可用于两个目的:更改参数打印的顺序(通常用于国际化),以及多次引用给定的参数。日期/时间格式字符t需要后面的第二个字符,例如年份的Y,月份的m等等。这里我们采用时间参数并从中提取几个字段:
msg = String.format(“Hello at%1 $ tB%1 $ td,%1 $ tY%n”,time);
这可能格式为2010年7月4日。
要以特定精度打印数字,可以使用宽度和精度的f,例如:
msg = String.format(“Latitude:%10.6f”,latitude);
这可能产生:
纬度:-79.281818
虽然这种格式化适用于特定用途,例如纬度和经度,对于一般使用如货币,它可能给你太多的控制。
一般格式化
Java有一个完整的包,java.text,充满格式化例程作为一般和灵活的任何你可能想象。与printf一样,它具有涉及的格式化语言,如在线文档页面中所述。考虑数字的表示。在北美,数字“一二四四”写作1,024.25;在欧洲的大部分地区是1 024,25,在世界的其他部分可能写作1.024,25。货币和百分比的格式也是不同的。试图自己跟踪这一切将推动平均软件开发商在弯曲相当快。
幸运的是,java.text包包含一个Locale类。此外,Java或Android运行时根据用户的环境自动设置默认的Locale对象;此代码在桌面Java上的工作方式与Android中的相同。为了提供为数字,货币和百分比自定义的格式化程序,NumberFormat类有静态工厂方法,通常返回具有已实例化的正确模式的DecimalFormat。适合用户区域设置的DecimalFormat对象可以从工厂方法NumberFormat.getInstance()获取并使用set方法进行处理。令人惊讶的是,方法setMinimumIntegerDigits()证明是生成带有前导零的数字格式的简单方法。例6-33是一个例子。

实例6-33。数字格式演示

import java.text.NumberFormat;
/*
* Format a number our way and the default way.
*/
public class NumFormat2 {
/** A number to format */
public static final double data[] = {
0, 1, 22d/7, 100.2345678
};
public static void main(String[] av) {
// Get a format instance
NumberFormat form = NumberFormat.getInstance();
// Tailor it to look like 999.99[99]
form.setMinimumIntegerDigits(3);
form.setMinimumFractionDigits(2);
form.setMaximumFractionDigits(4);
// Now print using it.
for (int i=0; i<data.length; i++)
System.out.println(data[i] + "\tformats as " +
form.format(data[i]));
}
}
这将使用NumberFormat实例窗体打印数组的内容。 我们将其作为主程序运行,而不是在Android应用程序中,以隔离NumberFormat的效果。
例如,$ java NumFormat2 0.0格式为000.00; 参数1.0,格式为001.00; 与3.142857142857143,它格式为003.1429; 并与100.2345678它格式为100.2346。
您还可以使用特定模式构造DecimalFormat或使用applyPattern()动态更改模式。 表6-2显示了一些更常见的模式字符。
表6-2。 DecimalFormat模式字符
Android 系列 6.27格式化数字

NumFormatTest程序使用一个DecimalFormat打印一个只有两个小数位的数字,一秒钟根据默认语言环境格式化数字,如例6-34所示。
实例6-34。 NumberFormat演示Java SE程序
import java.text.DecimalFormat;import java.text.NumberFormat;
public class NumFormatDemo {
/** A number to format */
public static final double intlNumber = 1024.25;
/** Another number to format */
public static final double ourNumber = 100.2345678;
public static void main(String[] av) {
NumberFormat defForm = NumberFormat.getInstance();
NumberFormat ourForm = new DecimalFormat("##0.##");
// toPattern() will reveal the combination of #0., etc.
// that this particular Locale uses to format with
System.out.println("defForm's pattern is " +
((DecimalFormat)defForm).toPattern());
System.out.println(intlNumber + " formats as " +
defForm.format(intlNumber));
System.out.println(ourNumber + " formats as " +
ourForm.format(ourNumber));
System.out.println(ourNumber + " formats as " +
defForm.format(ourNumber) + " using the default format");
}
}

这个程序打印给定的模式,然后格式化相同的数字使用几种格式:
$ java NumFormatTestdefForm's pattern is #,##0.###
1024.25 formats as 1,024.25
100.2345678 formats as 100.23
100.2345678 formats as 100.235 using the default format