1. 程式人生 > >Android 系列 6.27格式化數字

Android 系列 6.27格式化數字

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。一些常見的格式程式碼


預設的日期格式很醜,所以我們經常需要展開它。 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模式字元


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 NumFormatTest
defForm'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