Java Format 格式化

<hr/>java

Format

該類是個抽象基類,具體子類必須實現:git

//將對象格式化爲指定模式的字符串
format(Object obj, StringBuffer toAppendTo, FieldPosition pos)

//將字符串從新解析爲對象 
parseObject(String source, ParsePosition pos)

DateFormat(格式化日期時間)

DateFormat根據當前語言環境格式化日期和時間。數組

DateFormat是一個抽象類,因此不能直接new建立實例對象。但該類爲咱們提供了工廠方法方便咱們使用。安全

  • getDateInstance() ——獲取格式化的日期:2015-2-12
  • getTimeInstance() ——獲取格式化的時間:23:33:33
  • getDateTimeInstance() ——獲取格式化的日期和時間:2015-2-12
  • getInstance() ——獲取格式化的日期和時間:15-2-12 下午11:33

也許你會發現,在這些工廠發放中容許咱們傳入一個int參數,該參數容許咱們設定格式化風格,從而獲得咱們相對理想的結果。下表中對應了不一樣的style值和輸出樣式(這些常量值都在DateFormat類中)app

樣式值 日期 時間
SHORT 17-12-22 上午09:00
MEDIUM 2017-12-22 09:00:00
LONG 2015年12月22日 上午09時00分00秒
FULL 2015年12月22日 星期二 上午09時00分00秒 CST
DEFAULT 2015-12-22 09:00:00

固然你也能夠指定語言環境獲取該語言環境下的格式化日期和時間學習

//獲取加拿大的格式化日期
DateFormat format = DateFormat.getDateInstance(DateFormat.DEFAULT,Locale.CANADA);

SimpleDateFormat

SimpleDateFormat是DateFormat的一個具體類,它容許咱們指定格式模式從而獲取咱們理想的格式化日期和時間。測試

經過構造方法能夠傳入一個自定義格式的日期和時間
對於格式模式字符串,API爲咱們提供了豐富的模式元素,下面列出幾個經常使用的模式元素spa

字母 日期或時間元素 示例
y 2015
M 年中的月份 12
w 年中的週數 50
W 月份中的週數 02
D 年中的天數 344
d 月份中的天數 10
F 月份中的星期 02
E 星期中的天數 星期4、Thu
a AM/PM標記 下午、PM
H 一天中的小時數(0~23) 21
k 一天中的小時數(1~24) 21
K am/pm中的小時數(0~11) 09
h am/pm中的小時數(1~12) 09
m 小時中的分鐘數 31
s 分鐘中的秒數 08
S 毫秒數 716

若是你設置Locale的話,會有不一樣的顯示格式,好比若是設置Locale.ENGLISH,E會顯示爲英文格式,a顯示爲AM或PM線程

Date date = new Date();
SimpleDateFormat format = new SimpleDateFormat("今天是yyyy-MM-dd E hh:mm:ss,是yyyy年的第DD天,在該月是第dd天");

System.out.println(format.format(date));

將會輸出:今天是2015-12-10 星期四 09:38:16,是2015年的第344天,在該月是第10天code

<br/> <hr/>

NumberFormat(格式化數字)

NumberFormat根據當前語言環境格式化數字
NumberFormat一樣是一個抽象基類,可使用API中的工廠方法獲取實例對象

  • getCurrencyInstance() ——根據語言環境獲取貨幣數值格式
  • getInstance() ——獲取常規數值格式
  • getIntegetInstance() ——獲取整數值格式,若是是小數則會四捨五入
  • getPercentInstance() ——獲取百分比數值格式

DecimalFormat(子類)

DecimalFormat同SimpleDateFormat相似,容許咱們指定格式模式獲取咱們想要的格式化數值

DecimalFormat類對於數值的小數部分,默認顯示3位小數,在去掉超出小數點後面3位的部分時,會將數值四捨五入爲最接近的數值格式化輸出。固然咱們能夠對這個默認進行設置

  • DecimalFormat() ——獲取自定義格式化數值 (對於小數部分,默認顯示3位小數,超過則四捨五入)
  • setMaximumFractionDigits( int ) ——設置小數部分容許顯示的最大數位
  • setMinimumFractionDigits( int ) ——設置小數部分容許顯示的最小數位,若是不夠就補零
標識 含義
0 表示一個數字,被格式化數值不夠的位數會補0
# 表示一個數字,被格式化數值不夠的位數會忽略
. 小數點分隔符的佔位符
, 分組分隔符的佔位符
- 缺省負數前綴
% 將數值乘以100並顯示爲百分數
\u2030 將數值乘以1000並顯示爲千分數
DecimalFormat format1 = new DecimalFormat("#\u2030");
System.out.println(format1.format(0.3345));
//輸出334‰

DecimalFormat format2 = new DecimalFormat("##.##");
System.out.println(format2.format(12.345));
//輸出12.35

DecimalFormat format3 = new DecimalFormat("0000.00");
System.out.println(format3.format(12.345));
//輸出0012.35

DecimalFormat format4 = new DecimalFormat("#.##%");
System.out.println(format4.format(12.345));
//輸出1234.5%

<br/> <hr/>

ChoiceFormat

容許將格式化運用到某個範圍的數,一般與MessageFormat一同使用。ChoiceFormat在構造方法中接收一個format數組和一個limits數組,這兩個數組的長度必須相等,例如:

limits = {1,2,3,4,5,6,7}
formats = {"Sun","Mon","Tue","Wed","Thur","Fri","Sat"}

limits數組其實是個區間,可開可閉,而且必須按升序排列,若是不按升序排列,格式化結果將會不正確,還可使用\u221E(表示無窮大)。
ChoiceFormat的匹配公式

limit[j] <= X <limit[j+1]

其中X表示使用format方法傳入的值,j表示limit數組中的索引。當且僅當上述公式成立時,X匹配j,若是不能匹配,則會根據X是過小仍是太大,匹配limits數組的第一個索引或最後一個索引,而後使用匹配的limits數組中的索引,去formats數組中尋找相同索引的值。例子:

double[] limits = { 3, 4, 5, 6, 7, 8, 9 };
String[] formats = { "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日" };
ChoiceFormat format = new ChoiceFormat(limits, formats);
System.out.println(format.format(2.5));//將會輸出"星期一"
/**3.6介於3和4之間,因此會匹配3,又因爲3在limits數組中的索引是0,因此會在formats數組徐照索引0的值,即輸出"星期一"
*/
System.out.println(format.format(3.6));

下面看一下ChoiceFormat類中的幾個經常使用方法

  • nextDouble(double d) ——查找大於d的最小double值,用在limits數組中,從而使limits數組造成一個右開區間數組,例如

    limits = {0,1,ChoiceFormat.nextDouble(1)}

  • nextDouble(double d, boolean positive) ——若是positive參數爲true,表示查找大於d的最小double值;若是positive參數爲false,表示查找小於d的最大double值,這樣就可使limits造成一個左開區間數組。
  • previousDouble(double d) ——查找小於d的最大double值

ChoiceFormat類的構造方法也容許咱們傳入一個模式字符串,format方法會根據這個模式字符串執行格式化操做。一個模式元素的格式以下:

doubleNum [佔位符] formatStr

佔位符可使用#、< 、\u2264(<=)

ChoiceFormat cf = new ChoiceFormat("1#is 1 | 1<is more than 1");
System.out.println(cf.format(1));//輸出"is 1"
System.out.println(cf.format(2));//輸出"is more than 1"
System.out.println(cf.format(0));//輸出"is 1"

由上面的例子能夠看出,模式字符串中的每一個模式元素之間使用"|"分割,"|"先後能夠添加空格以美化代碼,並且必須按照升序進行書寫,不然會出現java.lang.IllegalArgumentException的運行時異常。

觀看ChoiceFormat類的源碼咱們得知,實際上在內部,模式字符串仍是被轉換爲limits和formats兩個數組。在源碼中

public ChoiceFormat(String newPattern)  {
     applyPattern(newPattern);
}
/** applyPattern(newPattern)方法的部分源碼
*/
public void applyPattern(String newPattern) {
    ...
    choiceLimits = new double[count];
    System.arraycopy(newChoiceLimits, 0, choiceLimits, 0, count);
    choiceFormats = new String[count];
    System.arraycopy(newChoiceFormats, 0, choiceFormats, 0, count);
    ...
}

能夠看出ChoiceFormat(String newPattern)調用了applyPattern(String newPattern)方法,在applyPattern方法中對newPattern字符串進行解析,而後將解析後的數據放置到ChoiceFormat類的兩個私有屬性double[] choiceLimits和String[] choiceFormats中,而後使用格式化方法便可。

<br/> <hr/>

MessageFormat

MessageFormat提供了以語言環境無關的生成鏈接消息的方式。

經常使用MessageFormat的靜態方法format,該方法接收一個字符串的模式和一組對象(對象數組),按照模式形式將格式化的對象插入到模式中,而後返回字符串結果。

MessageFormat的格式模式元素(FormatElement)形式以下:

  • {ArgumentIndex}
  • {ArgumentIndex,FormatType}
  • {ArgumentIndex,FormatType,FormatStyle}

其中ArgumentIndex對象數組中的索引,從0開始, FormatType包括number、date、 time、choice, FormatStyle包括short、medium、long、full、integer、currency、percent、SubformatPattern(子模式),

在MessageFormat類的內部,FormatType和FormatStyle其實是建立格式元素的Format示例
number對應了NumberFormat,其子格式對應了DecimalFormat
date和time對應了DateFormat,其資格是對應了SimpleDateFormat
choice對應了ChoiceFormat

你能夠直接使用MessageFormat類中的靜態方法format,像這樣:

/**這是源碼註釋中的一個例子
* 在這個例子中靜態方法format第一個參數是字符串類型的,
* 即模式字符串,第二個參數是個可變參數,實際上就是一個Object類型的數組。
* 在模式字符串中使用"{}"標識一個FormatElement。"{}"中的ArgumentIndex對應Object數組中響應索引處的值。
*/
int planet = 7;
String event = "a disturbance in the Force";
String result = MessageFormat.format("At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.",
                  planet, new Date(), event);
System.out.println(result);
//輸出:At 20:39:15 on 2015-12-11, there was a disturbance in the Force on planet 7.

你也可使用MessageFormat的構造方法傳入pattern string(模式字符串),而後調用普通的format方法,在這裏就不舉栗子了。

咱們不只被容許使用MessageFormat類中提供默認的FormatElement去format這些對象,還能夠設置本身的Format對象format這些Object。

/**在這個例子中,MessageFormat和ChoiceFormat被結合使用
* MessageFormat類中有3個方法值的咱們關注
* 1.setFormatByArgumentIndex(int argumentIndex, Format newFormat)//
* 2.setFormats(Format[] newFormats)
* 3.setFormat(int formatElementIndex, Format newFormat)
* 在這個例子當中,在MessageFormat的模式字符串的FormatElement(即{}中的內容)中
* 索引爲0的地方將使用ChoiceFormat的格式去格式化。
* 若是在set的Format中仍具備FormatElement,則會遞歸調用MessageFormat的format方法。
*/
MessageFormat form = new MessageFormat("The disk \"{1}\" contains {0}.");
double[] filelimits = { 0, 1, 2 };
String[] filepart = { "no files", "one file", "{0,number} files" };
ChoiceFormat fileform = new ChoiceFormat(filelimits, filepart);
form.setFormatByArgumentIndex(0, fileform);
int fileCount = 1273;
String diskName = "MyDisk";
Object[] testArgs = { new Long(fileCount), diskName };
System.out.println(form.format(testArgs));
//輸出:The disk "MyDisk" contains 1,273 files.

<br/> <hr/>

StringFormat(字符串格式化)

format方法使用佔位符進行格式化 常規類型、字符類型和數值類型的佔位符格式:

%[index$][標識][最小寬度][.精度]轉換符

日期和時間類型的佔位符格式:

%[index$][標識][最小寬度]轉換符

與參數不對應的佔位符格式:

%[標識][最小寬度]轉換符

其中index表示參數列表中的位置上的值

可用標識:

標識 含義
- 在最小寬度內左對齊,不可與0標識一塊兒使用
0 若內容長度不足最小寬度,則在左邊用0來填充
# 對8進制和16進制,8進制前添加一個0,16進制前添加0x
+ 結果總包含一個+或-號
空格 正數前加空格,負數前加-號
, 只用與十進制,每3位數字間用,分隔
( 若結果爲負數,則用括號括住,且不顯示符號

可用轉換符: 轉換符 | 含義 :-: | :-: b | 布爾類型,只要實參爲非false的布爾類型,均格式化爲字符串true,不然爲字符串false n | 平臺獨立的換行符, 也可經過System.getProperty("line.separator")獲取 f | 浮點數型(十進制)。顯示9位有效數字,且會進行四捨五入。如99.99 a | 浮點數型(十六進制) e | 指數類型。如9.38e+5 g | 浮點數型(比%f,%a長度短些,顯示6位有效數字,且會進行四捨五入) s | 字符串類型 c | 字符類型

String.format("小明%d歲,住在%s,月工資有%.2f", 25,"北京市",6633.435);
輸出:小明今年25歲,他住在北京市,他的月工資有6633.44

double num = 123.4567899;
String result2 = String.format("%e", num);
輸出:1.234568e+02

總結

  1. Format中的子類都是不一樣步,因此須要注意線程安全問題
  2. 學習最重要的是多去嘗試,多編寫代碼測試

<br/> <hr/>

相關文章
相關標籤/搜索