Java中強大的format

Java中允許我們對指定的對象進行某種格式化,從而得到我們想要的格式化樣式赵刑。

Format

首先介紹java.text包中的Format
Foramt是一個抽象基類分衫,其具體子類必須實現(xiàn)

format(Object obj, StringBuffer toAppendTo, FieldPosition pos)

parseObject(String source, ParsePosition pos)

兩個抽象方法。
format方法用于將對象格式化為指定模式的字符串
parseObject方法用于將字符串重新解析為對象
Format的直接子類包括DateFormat般此、NumberFormatMessageFormat蚪战。下面一一進行介紹

1.DateFormat

DateFormat根據(jù)當前語言環(huán)境格式化日期和時間。
DateFormat是一個抽象類铐懊,所以不能直接new創(chuàng)建實例對象邀桑。但該類為我們提供了工廠方法方便我們使用。
1.getDateInstance()方法科乎,獲取格式化的日期壁畸,輸出樣式:2015-12-10
2.getDateTimeInstance()方法,獲取格式化的日期和時間,輸出樣式:2015-12-10 10:21:41
3.getTimeInstance()方法茅茂,獲取格式化的時間捏萍,輸出樣式:10:21:41
4.getInstance()方法,獲取格式化的日期和時間空闲,輸出樣式:15-12-10 上午10:21
也許你會發(fā)現(xiàn)令杈,在這些工廠發(fā)放中允許我們傳入一個int參數(shù),該參數(shù)允許我們設定格式化風格碴倾,從而得到我們相對理想的結果逗噩。下表中對應了不同的style值和輸出樣式(這些常量值都在DateFormat類中)

樣式值 日期 時間
SHORT 15-12-10 上午10:08
MEDIUM 2015-12-10 10:09:23
LONG 2015年12月10日 上午10時09分40秒
FULL 2015年12月10日 星期四 上午10時17分30秒 CST
DEFAULT 2015-12-10 10:18:07

當然你也可以指定語言環(huán)境獲取該語言環(huán)境下的格式化日期和時間,

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

也許你要發(fā)問了跌榔,上面的格式沒有我一個想要的啊异雁。那好,這里還有一個好東西

SimpleDateFormat

SimpleDateFormatDateFormat的一個具體類僧须,它允許我們指定格式模式從而獲取我們理想的格式化日期和時間纲刀。
通過SimpleDateFormat的構造方法你可以傳入一個格式模式字符串或者通過applyPattern(String pattern)方法添加一個格式模式字符串。
對于格式模式字符串皆辽,API為我們提供了豐富的模式元素柑蛇,下面列出幾個常用的模式元素

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

2.NumberFormat

NumberFormat根據(jù)當前語言環(huán)境格式化數(shù)字
NumberFormat同樣是一個抽象基類循榆,可以使用API中的工廠方法獲取實例對象
1.getCurrencyInstance()方法析恢,根據(jù)當前語言環(huán)境獲取貨幣數(shù)值格式。傳遞Locale對象可以獲取指定語言環(huán)境下的貨幣數(shù)值格式秧饮,比如

NumberFormat format = NumberFormat.getCurrencyInstance(Locale.CANADA);
System.out.println(format.format(439.6));
將會輸出:$439.60

2.getInstance()getNumberInstance()方法都會獲取到常規(guī)數(shù)值格式
3.getIntegerInstance()方法獲取常規(guī)整數(shù)值格式映挂,如果需要格式化的數(shù)值為小數(shù),則會將數(shù)值四舍五入為最接近的整數(shù)
4.getPercentInstance()方法獲取百分比的數(shù)值格式
NumberFormat有兩個具體實現(xiàn)子類DecimalFormatChoiceFormat

DecimalFormat

DecimalFormat同SimpleDateFormat類似盗尸,允許我們指定格式模式獲取我們想要的格式化數(shù)值
DecimalFormat類對于數(shù)值的小數(shù)部分柑船,默認顯示3位小數(shù),在去掉超出小數(shù)點后面3位的部分時泼各,會將數(shù)值四舍五入為最接近的數(shù)值格式化輸出鞍时。淡然我們可以對這個默認進行設置
setMaximumFractionDigits(int newValue)方法,設置小數(shù)部分中允許的最大數(shù)字位數(shù)
setMinimumFractionDigits(int newValue)方法扣蜻,設置小數(shù)部分中允許的最小數(shù)字位數(shù)逆巍,如果原數(shù)小數(shù)位數(shù)不夠的話,會補零莽使。
對于數(shù)值的整數(shù)部分锐极,默認3個數(shù)字為一組進行顯示,同樣對此我們也可以自定義吮旅,使用setGroupingSize(int i)方法溪烤,設置分組中一組的位數(shù)。
setGroupingUsed(boolean value)方法設置是否使用分組庇勃,true表示使用檬嘀,false表示取消分組
setMaximumIntegerDigits(int newValue)方法設置整數(shù)部分允許的最大數(shù)字位數(shù)
setMinimumIntegerDigits(int newValue)方法設置整數(shù)部分允許的最小數(shù)字位數(shù)
在````的構造方法中,允許我們傳入格式模式字符串輸出我們想要的格式化數(shù)值责嚷,格式模式元素包含如下

||
----|------------|------
0 | 表示一個數(shù)字鸳兽,被格式化數(shù)值不夠的位數(shù)會補0

| 表示一個數(shù)字,被格式化數(shù)值不夠的位數(shù)會忽略

. | 小數(shù)點分隔符的占位符
, | 分組分隔符的占位符

  • | 缺省負數(shù)前綴
    % | 將數(shù)值乘以100并顯示為百分數(shù)
    \u2030 | 將數(shù)值乘以1000并顯示為千分數(shù)

    再次
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%
ChoiceFormat

ChoiceFormat允許將格式化運用到某個范圍的數(shù)罕拂,通常與MessageFormat一同使用揍异。ChoiceFormat在構造方法中接收一個format數(shù)組和一個limits數(shù)組,這兩個數(shù)組的長度必須相等爆班,例如:

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

limits數(shù)組實際上是個區(qū)間衷掷,可開可閉,并且必須按升序排列柿菩,如果不按升序排列戚嗅,格式化結果將會不正確,還可以使用\u221E(表示無窮大)。
ChoiceFormat的匹配公式

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

其中X表示使用format方法傳入的值懦胞,j表示limit數(shù)組中的索引替久。當且僅當上述公式成立時,X匹配j躏尉,如果不能匹配蚯根,則會根據(jù)X是太小還是太大,匹配limits數(shù)組的第一個索引或最后一個索引胀糜,然后使用匹配的limits數(shù)組中的索引颅拦,去formats數(shù)組中尋找相同索引的值。例子:

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數(shù)組中的索引是0,所以會在formats數(shù)組徐照索引0的值怖竭,即輸出"星期一"
*/
System.out.println(format.format(3.6));

下面看一下ChoiceFormat類中的幾個常用方法
1.nextDouble(double d)靜態(tài)方法查找大于d的最小double值锥债,用在limits數(shù)組中,從而使limits數(shù)組形成一個右開區(qū)間數(shù)組痊臭,例如
limits = {0,1,ChoiceFormat.nextDouble(1)}
2.nextDouble(double d, boolean positive)靜態(tài)方法哮肚,如果positive參數(shù)為true,表示查找大于d的最小double值广匙;如果positive參數(shù)為false允趟,表示查找小于d的最大double值,這樣就可以使limits形成一個左開區(qū)間數(shù)組鸦致。
3.previousDouble(double d)靜態(tài)方法潮剪,查找小于d的最大double值
ChoiceFormat類的構造方法也允許我們傳入一個模式字符串,format方法會根據(jù)這個模式字符串執(zhí)行格式化操作分唾。一個模式元素的格式如下:

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"

由上面的例子可以看出绽乔,模式字符串中的每個模式元素之間使用"|"分割弧蝇,"|"前后可以添加空格以美化代碼,而且必須按照升序進行書寫折砸,否則會出現(xiàn)java.lang.IllegalArgumentException的運行時異常看疗。
觀看ChoiceFormat類的源碼我們得知,實際上在內部睦授,模式字符串還是被轉換為limits和formats兩個數(shù)組两芳。在源碼中

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字符串進行解析去枷,然后將解析后的數(shù)據(jù)放置到ChoiceFormat類的兩個私有屬性double[] choiceLimitsString[] choiceFormats中盗扇,然后使用格式化方法即可祷肯。

3.MessageFormat

MessageFormat提供了以語言環(huán)境無關的生成連接消息的方式沉填。
常用MessageFormat的靜態(tài)方法format疗隶,該方法接收一個字符串的模式和一組對象(對象數(shù)組),按照模式形式將格式化的對象插入到模式中翼闹,然后返回字符串結果斑鼻。
MessageFormat的格式模式元素(FormatElement)形式如下:
{ArgumentIndex}
{ArgumentIndex,FormatType}
{ArgumentIndex,FormatType,FormatStyle}
其中ArgumentIndex對象數(shù)組中的索引,從0開始猎荠,
FormatType包括number坚弱、date、 time关摇、choice荒叶,
FormatStyle包括short、medium输虱、long些楣、full、integer宪睹、currency愁茁、percent、SubformatPattern(子模式)亭病,
在MessageFormat類的內部鹅很,F(xiàn)ormatType和FormatStyle實際上是創(chuàng)建格式元素的Format示例
number對應了NumberFormat,其子格式對應了DecimalFormat
date和time對應了DateFormat罪帖,其資格是對應了SimpleDateFormat
choice對應了ChoiceFormat
敢說沒有意思促煮,來多舉幾個栗子:
你可以直接使用MessageFormat類中的靜態(tài)方法format,像這樣:

/**這是源碼注釋中的一個例子
* 在這個例子中靜態(tài)方法format第一個參數(shù)是字符串類型的整袁,
* 即模式字符串菠齿,第二個參數(shù)是個可變參數(shù),實際上就是一個Object類型的數(shù)組葬项。
* 在模式字符串中使用"{}"標識一個FormatElement泞当。"{}"中的ArgumentIndex對應Object數(shù)組中響應索引處的值。
*/
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.

4.String類中的format方法

format方法使用占位符進行格式化
常規(guī)類型梨州、字符類型和數(shù)值類型的占位符格式:
%[index$][標識][最小寬度][.精度]轉換符
日期和時間類型的占位符格式:
%[index$][標識][最小寬度]轉換符
與參數(shù)不對應的占位符格式:
%[標識][最小寬度]轉換符
其中index表示參數(shù)列表中的位置上的值
可用標識:

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

可用轉換符:

轉換符 含義
b 布爾類型,只要實參為非false的布爾類型窒典,均格式化為字符串true蟆炊,否則為字符串false
n 平臺獨立的換行符, 也可通過System.getProperty("line.separator")獲取
f 浮點數(shù)型(十進制)。顯示9位有效數(shù)字瀑志,且會進行四舍五入涩搓。如99.99
a 浮點數(shù)型(十六進制)
e 指數(shù)類型。如9.38e+5
g 浮點數(shù)型(比%f后室,%a長度短些缩膝,顯示6位有效數(shù)字,且會進行四舍五入)
s 字符串類型
c 字符類型
String result1 = String.format("小明今年%d歲,他住在%s,他的月工資有%.2f", 25,"北京市",6633.435);
System.out.println(result1);//輸出:小明今年25歲,他住在北京市,他的月工資有6633.44
/*****************************************************/
double num = 123.4567899;
String result2 = String.format("%e", num);
System.out.println(result2);//輸出:1.234568e+02

總結

1.Format中的子類都是不同步岸霹,所以需要注意線程安全問題
2.可能在某些地方我解釋的還是不太清楚疾层。學習最重要的是多去嘗試,多編寫代碼測試贡避,如果僅僅靠看就能學會的話痛黎,那你就看吧、

以上是對自己學習的總結刮吧,如有錯誤的地方請?zhí)岢鰜砗ィ視皶r更改的,謝謝I蹦怼>帷!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末致讥,一起剝皮案震驚了整個濱河市仅仆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌垢袱,老刑警劉巖墓拜,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異请契,居然都是意外死亡咳榜,警方通過查閱死者的電腦和手機夏醉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涌韩,“玉大人畔柔,你說我怎么就攤上這事∶潮玻” “怎么了释树?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長擎淤。 經常有香客問我,道長秸仙,這世上最難降的妖魔是什么嘴拢? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮寂纪,結果婚禮上席吴,老公的妹妹穿的比我還像新娘。我一直安慰自己捞蛋,他們只是感情好孝冒,可當我...
    茶點故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著拟杉,像睡著了一般庄涡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上搬设,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天穴店,我揣著相機與錄音,去河邊找鬼拿穴。 笑死泣洞,一個胖子當著我的面吹牛,可吹牛的內容都是我干的默色。 我是一名探鬼主播球凰,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼腿宰!你這毒婦竟也來了呕诉?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤酗失,失蹤者是張志新(化名)和其女友劉穎义钉,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體规肴,經...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡捶闸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年夜畴,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片删壮。...
    茶點故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡贪绘,死狀恐怖,靈堂內的尸體忽然破棺而出央碟,到底是詐尸還是另有隱情税灌,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布亿虽,位于F島的核電站菱涤,受9級特大地震影響,放射性物質發(fā)生泄漏洛勉。R本人自食惡果不足惜粘秆,卻給世界環(huán)境...
    茶點故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望收毫。 院中可真熱鬧攻走,春花似錦、人聲如沸此再。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽输拇。三九已至摘符,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間淳附,已是汗流浹背议慰。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留奴曙,地道東北人别凹。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像洽糟,于是被迫代替她去往敵國和親炉菲。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,440評論 2 359

推薦閱讀更多精彩內容

  • 第5章 引用類型(返回首頁) 本章內容 使用對象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學一百閱讀 3,238評論 0 4
  • 一坤溃、EL表達式簡介 1.EL全名為Expression Language拍霜。主要作用: 獲取數(shù)據(jù):EL表達式主要用于...
    yjaal閱讀 3,925評論 2 28
  • longaaaa =14200666; Console.WriteLine(aaaa.ToString("N0")...
    魚落于天閱讀 919評論 0 1
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn)薪介,斷路器祠饺,智...
    卡卡羅2017閱讀 134,693評論 18 139
  • 昨天我們講了肥胖的話題,今天我們接著聊汁政。 我們都知道道偷,肝是健康的大總管缀旁,也是人體內脂肪代謝的場所,食物中的...
    暖洋洋說生活閱讀 1,448評論 0 2