Java MessageFormat.format和ChoiceFormat

Coding-lover發表於2015-11-10

一、前言

剛開始從.net的轉向java的時候總覺得 String.format 用得不習慣,希望格式模版會這樣 {0}, this is {1}'s cat.{1},this is {0}'s dog. 而不是 %1\$s,this is %2$s's cat.%2$s,this is %1$s's dog. 。後來發現 java.text.MessageFormat.format 可以滿足我這個小小的願望。

二、靜態方法 java.text.MessageFormat.format

方法定義:

String MessageFormat.format(String fmt, Object...args)

入參fmt為MessageFormat模式引數。

三、MessageFormat模式

格式:ArgumentIndex[,FormatType[,FormatStyle]]

ArgumentIndex ,是從0開始的入參位置索引。

FormatType ,指定使用不同的Format子類對入參進行格式化處理。值範圍如下:

  • number:呼叫NumberFormat進行格式化
  • date:呼叫DateFormat進行格式化
  • time:呼叫DateFormat進行格式化
  • choice:呼叫ChoiceFormat進行格式化

FormatType ,設定FormatType中使用的格式化樣式。值範圍如下:

short,medium,long,full,integer,currency,percent,SubformPattern(子格式模式,形如#.##)

注意: FormatTypeFormatStyle 主要用於對日期時間、數字、百分比等進行格式化。

示例——將數字1.23格式為1.2:

double num = 1.23;
String str = MessageFormat.format("{0,number,#.#}", num);

四、MessageFormat注意點

  1. 兩個單引號才表示一個單引號,僅寫一個單引號將被忽略。

  2. 單引號會使其後面的佔位符均失效,導致直接輸出佔位符。

MessageFormat.format("{0}{1}", 1, 2); // 結果12
MessageFormat.format("'{0}{1}", 1, 2); // 結果{0}{1}
MessageFormat.format("'{0}'{1}", 1, 2); // 結果{0}

因此可以用於輸出左花括號(單寫左花括號會報錯,而單寫右花括號將正常輸出)

MessageFormat.format("'{'{0}}", 2); // 結果{2

因此前言中的示例應該寫為

{0}, this is {1}''s cat.{1},this is {0}''s dog.

五、類層級關係

                          |-- java.text.MessageFormat

頂層抽象類java.text.Format—|                          |--java.text.ChoiceFormat

                          |--java.text.NumberFormat—|

                |                 |--java.text.DecimalFormat

                |

                         |--java.text.DateFormat—java.text.SimpleDateFormat

1. DecimalFormat

用於格式化十進位制實數。通過格式字串來自定義格式化型別,舍入方式為half-even(四捨五入)。

格式化模式: 正數子模式;負數子模式 ,如 0.00;-0.00 ,簡寫為 0.00

模式中的佔位符:

  • 0 ,代表該為位為數字,若不存在則用0填充
  • # ,代表該為位為數字
  • , ,代表分隔符, 如模式為 #,# ,那麼格式化10時會返回1,0

2. ChoiceFormat

相當於以數字為鍵,字串為值的鍵值對。分別使用一組double型別的陣列作為鍵,一組String型別的陣列作為值,兩陣列相同索引值的元素作為一對。

示例——基本用法

double[] limit = {0,1,3};
String[] format = {"hello0", "hello1", "hello3"};
ChoiceFormat cf = new ChoiceFormat(limit, format);
for(int i = 0; i < 4; ++i){
  System.out.println(cf.format(i));
}
/* 輸出
 * hello0
 * hello1
 * hello0
 * hello3
 */

注意:當找不到對應的鍵值對時,則使用第一或最後一對鍵值對。

示例——結合MessageFormat使用

double[] limit = {0, 1};
String[] format = {"Hello0", "Hello1{1}"};
ChoiceFormat cf = new ChoiceFormat(limit, format);
MessageFormat mf = new MessageFormat("{0}");
mf.setFormatByArgumentIndex(0, cf);
for (int i = 0; i < 2; ++i){
    System.out.println(mf.format(new Object[]{new Integer(i), new Integer(i+1)}));
}
/* 輸出
 * Hello0
 * Hello12
 */

六、效能問題

由於靜態方法 MessageFormat.format 內部是

public static String format(String pattern, Object ... arguments)   
{  
    MessageFormat temp = new MessageFormat(pattern);  
    return temp.format(arguments);  
}  

因此若要多次格式同一個模式的字串,那麼建立一個MessageFormat例項在執行格式化操作比較好些。

七、總結

對於簡單的格式化或字串組裝, MessageFormat.format方法 使用更方便些,但要格式化處理更豐富的話要是用 String.format方法 吧!

轉載自:Java魔法堂:初探MessageFormat.format和ChoiceFormat
參考:JAVA學習(十)__MessageFormat用法

相關文章