Java DecimalFormat

分類:編程 時間:2016-11-06
[摘要:界說參考 http://download.Oracle.com/techNetwork/Java/javase/6/docs/zh/api/java/text/DecimalFormat.html 1、界說 DecimalFormat 是 NumberFormat 的一個詳細子類,用於&#2]

定義參考 http://download.oracle.com/technetwork/java/javase/6/docs/zh/api/java/text/DecimalFormat.html

一、定義

DecimalFormat 是 NumberFormat 的一個具體子類,用於格式化十進制數字。該類設計有各種功能,使其能夠解析和格式化任意語言環境中的數,包括對西方語言、阿拉伯語和印度語數字的支持。它還支持不同類型的數,包括整數 (123)、定點數 (123.4)、科學記數法表示的數 (1.23E4)、百分數 (12%) 和金額 ($123)。所有這些內容都可以本地化。

要獲取具體語言環境的 NumberFormat(包括默認語言環境),可調用 NumberFormat 的某個工廠方法,如 getInstance()。通常不直接調用 DecimalFormat 的構造方法,因為 NumberFormat 的工廠方法可能返回不同於 DecimalFormat 的子類。如果需要自定義格式對象,可執行:

 NumberFormat f = NumberFormat.getInstance(loc);
 if (f instanceof DecimalFormat) {
     ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true);
 }
 

DecimalFormat 包含一個模式 和一組符號。可直接使用 applyPattern() 或間接使用 API 方法來設置模式。符號存儲在 DecimalFormatSymbols 對象中。使用 NumberFormat 工廠方法時,可從已本地化的 ResourceBundle 中讀取模式和符號。

模式

DecimalFormat 模式具有下列語法:
模式:
正數模式
正數模式負數模式
正數模式:
前綴opt 數字後綴opt
負數模式:
前綴opt 數字後綴opt
前綴:
除 \uFFFE、\uFFFF 和特殊字符以外的所有 Unicode 字符
後綴:
除 \uFFFE、\uFFFF 和特殊字符以外的所有 Unicode 字符
數字:
整數指數opt
整數小數指數opt
整數:
最小整數
         #
# 整數
# , 整數
最小整數:
         0
0 最小整數
0 , 最小整數
小數:
最小小數opt 可選小數opt
最小小數:
0 最小小數opt
可選小數:
# 可選小數opt
指數:
E 最小指數
最小指數:
0 最小指數opt
 

DecimalFormat 模式包含正數和負數子模式,例如 "#,##0.00;(#,##0.00)"。每個子模式都有前綴、數字部分和後綴。負數子模式是可選的;如果存在,則將用已本地化的減號(在多數語言環境中是 '-')作為前綴的正數子模式用作負數子模式。也就是說,單獨的 "0.00" 等效於 "0.00;-0.00"。如果存在顯式的負數子模式,則它僅指定負數前綴和後綴;數字位數、最小位數,其他特征都與正數模式相同。這意味著 "#,##0.0#;(#)" 的行為與 "#,##0.0#;(#,##0.0#)" 完全相同。

用於無窮大值、數字、千位分隔符、小數分隔符等的前綴、後綴和各種符號可設置為任意值,並且能在格式化期間正確顯示。但是,必須註意不要讓符號和字符串發生沖突,否則解析是不可靠的。例如,為了讓DecimalFormat.parse() 能夠區分正數和負數,正數和負數前綴或後綴必須是不同的。(如果它們相同,則 DecimalFormat 的行為就如同未指定負數子模式一樣。)另一個示例是小數分隔符和千位分隔符應該是不同的字符,否則將不可能進行解析。

分組分隔符通常用於千位,但是在某些國家/地區中它用於分隔萬位。分組大小是分組字符之間的固定數字位數,例如 100,000,000 是 3,而 1,0000,0000 則是 4。如果使用具有多個分組字符的模式,則最後一個分隔符和整數結尾之間的間隔才是使用的分組大小。所以 "#,##,###,####" == "######,####" == "##,####,####"

特殊模式字符

模式中的很多字符都是按字面解釋的;在解析期間對其進行匹配,在格式化期間則不經改變地輸出。另一方面,特殊字符代表了其他字符、字符串或字符類。如果要將其作為字面量出現在前綴或後綴中,那麽除非另行說明,否則必須對其加引號。

下列字符用在非本地化的模式中。已本地化的模式使用從此格式器的 DecimalFormatSymbols 對象中獲得的相應字符,這些字符已失去其特殊狀態。兩種例外是貨幣符號和引號,不將其本地化。

符號 位置 本地化? 含義 0 數字 是 阿拉伯數字 # 數字字 是 阿拉伯數字,如果不存在則顯示為 0 . 數字 是 小數分隔符或貨幣小數分隔符 - 數字 是 減號 , 數字 是 分組分隔符 E 數字 是 分隔科學計數法中的尾數和指數。在前綴或後綴中無需加引號。 ; 子模式邊界 是 分隔正數和負數子模式 % 前綴或後綴 是 乘以 100 並顯示為百分數 \u2030 前綴或後綴 是 乘以 1000 並顯示為千分數 ¤ (\u00A4) 前綴或後綴 否 貨幣記號,由貨幣符號替換。如果兩個同時出現,則用國際貨幣符號替換。如果出現在某個模式中,則使用貨幣小數分隔符,而不使用小數分隔符。 ' 前綴或後綴 否 用於在前綴或或後綴中為特殊字符加引號,例如 "'#'#" 將 123 格式化為 "#123"。要創建單引號本身,請連續使用兩個單引號:"# o''clock"

科學計數法

科學計數法中的數表示為一個尾數和一個 10 的幾次冪的乘積,例如可將 1234 表示為 1.234 x 10^3。尾數的範圍通常是 1.0 <= x < 10.0,但並非必需如此。可指示 DecimalFormat 僅通過某個模式 來格式化和解析科學計數法表示的數;目前沒有創建科學計數法格式的工廠方法。在這個模式中,指數字符後面緊跟著一個或多個數字字符即指示科學計數法。示例:"0.###E0" 將數字 1234 格式化為 "1.234E3"

  • 指數字符後面的數字位數字符數給出了最小的指數位數。沒有最大值。使用本地化的減號來格式化負數指數, 使用模式中的前綴和後綴。這就允許存在諸如 "0.###E0 m/s" 等此類的模式。
  • 最小和最大整數數字位數一起進行解釋:
    • 如果最大整數數字位數大於其最小整數數字位數並且大於 1,則強制要求指數為最大整數數字位數的倍數,並將最小整數數字位數解釋為 1。最常見的用法是生成工程計數法,其中指數是 3 的倍數,如"##0.#####E0"。使用此模式時,數 12345 格式化為 "12.345E3",123456 則格式化為 "123.456E3"
    • 否則通過調整指數來得到最小整數數字位數。示例:使用 "00.###E0" 格式化 0.00123 時得到 "12.3E-4"
  • 尾數中的有效位數是最小整數 和最大小數 位數的和,不受最大整數位數的影響。例如,使用 "##0.##E0" 格式化 12345 得到 "12.3E3"。要顯示所有位數,請將有效位數計數設置為零。有效位數不會影響解析。
  • 指數模式可能不包含分組分隔符。

舍入

DecimalFormat 提供 RoundingMode 中定義的舍入模式進行格式化。默認情況下,它使用 RoundingMode.HALF_EVEN

阿拉伯數字

為了進行格式化,DecimalFormat 使用 DecimalFormatSymbols 對象中所定義的、從已本地化的阿拉伯數字 0 開始的 10 個連續字符作為阿拉伯數字。為了進行解析,可識別 Character.digit 所定義的這些阿拉伯數字和所有 Unicode 十進制阿拉伯數字。

特殊值

NaN 被格式化為一個字符串,通常具有單個字符 \uFFFD。此字符串由 DecimalFormatSymbols 對象所確定。這是唯一不使用前綴和後綴的值。

無窮大的值被格式化為一個字符串,通常具有單個字符 \u221E,具有正數或負數前綴和後綴。無窮大值的字符串由 DecimalFormatSymbols 對象所確定。

將負零("-0")解析為

  • 如果 isParseBigDecimal() 為 true,則為 BigDecimal(0)
  • 如果 isParseBigDecimal() 為 false 並且 isParseIntegerOnly() 為 true,則為 Long(0)
  • 如果 isParseBigDecimal() 和 isParseIntegerOnly() 均為 false,則為 Double(-0.0)

同步

DecimalFormat 通常不是同步的。建議為每個線程創建獨立的格式實例。如果多個線程同時訪問某個格式,則必須保持外部同步。

二、代碼實戰

public class DecimalFormatDemo {

	public static void main(String[] args) {
		
		double d1 = 12.34;
		DecimalFormat df1 = new DecimalFormat("0");//12
		DecimalFormat df2 = new DecimalFormat("#");//12
		DecimalFormat df3 = new DecimalFormat(".0");//12.3
		DecimalFormat df4 = new DecimalFormat("0.0");//12.3
		DecimalFormat df5 = new DecimalFormat("#.#");//12.3
		DecimalFormat df6 = new DecimalFormat("000.000");//012.340
		DecimalFormat df7 = new DecimalFormat("###.###");//12.34
		log(df1.format(d1));
		log(df2.format(d1));
		log(df3.format(d1));
		log(df4.format(d1));
		log(df5.format(d1));
		log(df6.format(d1));
		log(df7.format(d1));
		
		double d2 = 1234567890;
		DecimalFormat df8 = new DecimalFormat(",##");//12,34,56,78,90
		DecimalFormat df9 = new DecimalFormat("##,###");//1,234,567,890
		//如果有多個分組模式(,),由最右邊的逗號和其右邊的占位符(0或#)決定
		DecimalFormat df10 = new DecimalFormat(",##,###");//1,234,567,890
		log(df8.format(d2));
		log(df9.format(d2));
		log(df10.format(d2));
		
		//分組分隔符(,)只能位於整數部分,不能位於小數部分
//		//error: java.lang.IllegalArgumentException: Malformed pattern ",##,###.#,"
//		DecimalFormat df11 = new DecimalFormat(",##,###.#,");
//		//error: java.lang.IllegalArgumentException: Malformed pattern ",##,###.#,#"
//		DecimalFormat df12 = new DecimalFormat(",##,###.#,#");
//		log(df11.format(d2));
//		log(df12.format(d2));
		
		//註意:"-"這個符號是"減號",它不能代表負號
		double d3 = 1;
		DecimalFormat df13 = new DecimalFormat("-#");//-1
		log(df13.format(d3));
		
		double d4 = -1;
		DecimalFormat df14 = new DecimalFormat("#");//-1
		DecimalFormat df15 = new DecimalFormat("-#");//--1
		log(df14.format(d4));
		log(df15.format(d4));
		
		//(%和\u2030)可放置在
		double d6 = 0.12345;
		DecimalFormat df16 = new DecimalFormat("0.00%");//12.35%
		DecimalFormat df17 = new DecimalFormat("%0.00");//%12.35
		//"\u2030"表示千分數,"‰"為千分號。另外,"\u2030"所代表的特殊符號就是"‰"
		DecimalFormat df18 = new DecimalFormat("0.00\u2030");//123.45‰
		DecimalFormat df19 = new DecimalFormat("\u20300.00");//‰123.45
		log(df16.format(d6));
		log(df17.format(d6));
		log(df18.format(d6));
		log(df19.format(d6));
		
		double d7 = 123456789;
		DecimalFormat df20 = new DecimalFormat("0.000E000");//1.235E008
		DecimalFormat df21 = new DecimalFormat("00.00E00");//12.35E07
		log(df20.format(d7));
		log(df21.format(d7));
		
		double d8 = 123;
		double d9 = -123;
		//子模式邊界(;)用於分割"正數"(前)和"負數"(後),采用不同的格式化方式,會替換掉負數前面的"負號"
		DecimalFormat df22 = new DecimalFormat("#;負數(#)");
		log(df22.format(d8));//123
		log(df22.format(d9));//負數(123)
		
		double d10 = 123.45;
		DecimalFormat df23 = new DecimalFormat("#\u00A4");//123¥
		DecimalFormat df24 = new DecimalFormat("\u00A4#");//¥123
		DecimalFormat df25 = new DecimalFormat("¤#");//¥123
		DecimalFormat df26 = new DecimalFormat("$#");//$123
		log(df23.format(d10));
		log(df24.format(d10));
		log(df25.format(d10));
		log(df26.format(d10));
		
		double d11 = 123456789.123456789;
		//用於在前綴或或後綴中為特殊字符加引號,引號(')必須成對。如果要輸出引號(')本身,則使用兩個連續的引號
		DecimalFormat df27 = new DecimalFormat("'#'#");//#123456789
		DecimalFormat df28 = new DecimalFormat("''#''");//'123456789'
		log(df27.format(d11));
		log(df28.format(d11));
		
		isDecimal("123");//yes
		isDecimal("123.123");//yes
		isDecimal("123.123.123");//not
		isDecimal("-123");//yes
		isDecimal("--123");//not
		
		double d12 = 123456.123456;
		DecimalFormat df29 = new DecimalFormat("#");
		//默認當沒有小數部分時,不會顯示分隔符(.)
		df29.setDecimalSeparatorAlwaysShown(true);
		log(df29.format(d12));//123456.
		
		DecimalFormat df30 = new DecimalFormat("#.#");
		DecimalFormat df31 = new DecimalFormat(",###.###");
		//某些國家"整數"和"小數"的分隔符是逗號(,)而分組符號才是點號(.)
		df29.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.ITALY));
		df30.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.ITALY));
		df31.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.ITALY));
		log(df29.format(d12));//12,
		log(df30.format(d12));//123456,1
		log(df31.format(d12));//123.456,123
	}

	public static final void log(String msg) {
		system.out.println(msg);
	}
	
	public static final void isDecimal(String value) {
		Pattern decimalPattern = Pattern.compile("-?\\d*(\\.\\d*)?");
		Matcher matcher = decimalPattern.matcher(value);
		log(value + " is" + (matcher.matches()?"":" not") + " a decimal");
	}
}

三、運行截圖



Tags: 阿拉伯 百分數 十進制 印度 Java

文章來源:


ads
ads

相關文章
ads

相關文章

ad