前言
以前用到要對數(shù)字格式的地方,都是直接到網(wǎng)上搜一下。拿過來能用就行。因為平時用的不多。但是最近的項目對這個用的多了。網(wǎng)上拿來的不夠用了。自己看了java源碼把這方面惡補了。而且最近也好長時間沒有寫博客了。正好寫一篇拋磚引玉吧。
如果你只想知道怎么用,可以直接看下面使用示例↓↓↓。三分鐘速成。
正文
如果你對java源碼比較了解。你會發(fā)現(xiàn)java對文字,數(shù)字的格式化,是有一個公共的父類的Format。
NumberFormat和DecimalFormat都是它的子類關于數(shù)字的。
DateFormat和SimpleDateFormat也是它的子類關于文字的。
當然今天只說NumberFormat和DecimalFormat。相信我,當你搞懂這兩個以后,那么DateFormat和SimpleDateFormat也是肯定會的。
首先,要特別注意的是 NumberFormat和DecimalFormat是線程不安全的。 這意味你如果同時有多個線程操作一個format實例對象,會出現(xiàn)意想不到的結果。
解決方法有兩個:
- 為每個線程都創(chuàng)建一個 format實例,通過ThreadLocal 來給每個線程都產(chǎn)生一個本地實例。如果你對ThreadLocal不了解,可以看我這篇文章:ThreadLocal 的用法以及內(nèi)存泄露(內(nèi)存溢出)
- 進行外部同步,這個就可以通過關鍵詞 synchronized來進行同步。如果 你不了解synchronized,可以看我這篇文章:synchronized 參數(shù) 及其含義
上面的這兩種方法呢,
第一種方法 **比較占用內(nèi)存多,但是速度快,效率高。并發(fā)。**第二種方法 **占用內(nèi)存少,效率低,耗費時間長,畢竟要排隊嘛,串行。**具體取舍,看項目的情況。
JavaAPI官方描述
NumberFormat
NumberFormat幫助您格式化和解析任何區(qū)域設置的數(shù)字。您的代碼可以完全獨立于小數(shù)點,千位分隔符的區(qū)域設置約定,甚至是使用的特定十進制數(shù)字,或者數(shù)字格式是否為十進制。
DecimalFormat
DecimalFormat是NumberFormat十進制數(shù)字格式的具體子類 。它具有多種功能,旨在解析和格式化任何語言環(huán)境中的數(shù)字,包括支持西方,阿拉伯語和印度語數(shù)字。它還支持不同類型的數(shù)字,包括整數(shù)(123),定點數(shù)(123.4),科學記數(shù)法(1.23E4),百分比(12%)和貨幣金額(123美元)。所有這些都可以本地化。
NumberFormat
獲取NumberFormat實例
//創(chuàng)建 一個整數(shù)格式 地區(qū)用系統(tǒng)默認的 NumberFormat integerNumber = NumberFormat.getIntegerInstance(Locale.getDefault());
- 使用getInstance或getNumberInstance獲取正常的數(shù)字格式。
- 使用getIntegerInstance得到的整數(shù)格式。
- 使用getCurrencyInstance來獲取貨幣數(shù)字格式。
- 使用getPercentInstance獲取顯示百分比的格式。
常用方法
由于API 的描述足夠詳細,所以我就直接截圖上來了。
使用示例
DecimalFormat是NumberFormat,所以,就不要單獨的為NumberFormat寫一個完整的示例了。只寫一下配合FieldPosition怎么使用的示例:
NumberFormat numberFormat = NumberFormat.getInstance(Locale.getDefault()); //整數(shù)部分不會每隔三個,就會有 " ," numberFormat.setGroupingUsed(false); //線程安全的字符串緩沖類 StringBuffer stringBuffer = new StringBuffer(); //構造參數(shù) 是Format子類里面的 自己特有的參數(shù),傳入就行 //構造 小數(shù)部分的,所以開始 beginIndex()是從小數(shù)點 后面算的, 但是0是從整個格式化數(shù)字,第一個算起, 包括 之間用于分組的 " ," FieldPosition fieldPosition = new FieldPosition(NumberFormat.FRACTION_FIELD); stringBuffer = numberFormat.format(1234.56789, stringBuffer, fieldPosition); System.out.println(stringBuffer.toString()); //小數(shù)部分, 所以 從5 開始 System.out.println(fieldPosition.getBeginIndex() + " " + fieldPosition.getEndIndex()); //切割字符串 System.out.println(stringBuffer.toString().substring(fieldPosition.getBeginIndex()));
運行結果
DecimalFormat
獲取DecimalFormat實例
要獲取特定地區(qū)(包括默認地區(qū))的NumberFormat,請調(diào)用NumberFormat的工廠方法之一,例如getInstance()。通常,不要直接調(diào)用DecimalFormat構造函數(shù),因為NumberFormat工廠方法可能返回DecimalFormat之外的子類。如果需要自定義format對象,可以這樣做:
try { NumberFormat f = NumberFormat.getInstance(Locale.getDefault()); if (f instanceof DecimalFormat) { ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true); //寫具體的代碼 } } catch (Exception e) { e.printStackTrace(); }
設置Pattern
DecimalFormat作為NumberFormat的具體實現(xiàn)子類,最大的特點就是 可以使用Pattern。來實現(xiàn)最大程度的對數(shù)據(jù)格式進行定制。
一個Pattern中的許多字符是按字面意思理解的;它們在解析期間匹配,在格式化期間輸出不變,就是字符在Pattern中 不影響最后的數(shù)字格式化另一方面,特殊字符代表其他字符、字符串或字符類。如果要以文字形式出現(xiàn)在前綴或后綴中,必須引用它們(除非另有說明)。
子類特有的方法
因為懶,而且這玩意是在簡單,大家就將就看個截圖吧。
使用示例
接下來就是萬眾矚目的示例代碼了,只要java基礎可以,一開始看這個完全就可以學會用法。
通用格式
//創(chuàng)建一個默認的通用格式 NumberFormat numberFormat = NumberFormat.getInstance(); DecimalFormat numberDecimalFormat; //捕捉異常,以防強制類型轉(zhuǎn)換出錯 try { //強制轉(zhuǎn)換成DecimalFormat numberDecimalFormat = (DecimalFormat) numberFormat; //保留小數(shù)點后面三位,不足的補零,前面整數(shù)部分 每隔四位 ,用 “,” 符合隔開 numberDecimalFormat.applyPattern("#,####.000"); //設置舍入模式 為DOWN,否則默認的是HALF_EVEN numberDecimalFormat.setRoundingMode(RoundingMode.DOWN); //設置 要格式化的數(shù) 是正數(shù)的時候。前面加前綴 numberDecimalFormat.setPositivePrefix("Prefix "); System.out.println("正數(shù)前綴 "+numberDecimalFormat.format(123456.7891)); //設置 要格式化的數(shù) 是正數(shù)的時候。后面加后綴 numberDecimalFormat.setPositiveSuffix(" Suffix"); System.out.println("正數(shù)后綴 "+numberDecimalFormat.format(123456.7891)); //設置整數(shù)部分的最大位數(shù) numberDecimalFormat.setMaximumIntegerDigits(3); System.out.println("整數(shù)最大位數(shù) "+numberDecimalFormat.format(123456.7891)); //設置整數(shù)部分最小位數(shù) numberDecimalFormat.setMinimumIntegerDigits(10); System.out.println("整數(shù)最小位數(shù) "+numberDecimalFormat.format(123456.7891)); //設置小數(shù)部分的最大位數(shù) numberDecimalFormat.setMaximumFractionDigits(2); System.out.println("小數(shù)部分最大位數(shù) "+numberDecimalFormat.format(123.4)); //設置小數(shù)部分的最小位數(shù) numberDecimalFormat.setMinimumFractionDigits(6); System.out.println("小數(shù)部分最小位數(shù) "+numberDecimalFormat.format(123.4)); }catch (Exception e){ e.printStackTrace(); }
運行結果
獲取百分比格式
對數(shù)字 進行 百分比 格式化
//創(chuàng)建一個中國地區(qū)的 百分比格式 NumberFormat perFormat = NumberFormat.getPercentInstance(Locale.CHINA); DecimalFormat percentFormat; try { percentFormat = (DecimalFormat) perFormat; //設置Pattern 會使百分比格式,自帶格式失效 // percentFormat.applyPattern("##.00"); //設置小數(shù)部分 最小位數(shù)為2 percentFormat.setMinimumFractionDigits(2); System.out.println(percentFormat.format(0.912345)); } catch (Exception e) { e.printStackTrace(); }
運行結果:
貨幣格式
//創(chuàng)建一個中國地區(qū)的 貨幣格式 NumberFormat curFormat = NumberFormat.getCurrencyInstance(Locale.CHINA); DecimalFormat currencyFormat; try { currencyFormat = (DecimalFormat) curFormat; //設置Pattern 會使百分比格式,自帶格式失效 // currencyFormat.applyPattern("##.00"); System.out.println(currencyFormat.format(0.912345)); //乘法 數(shù)乘以多少 這個方法是 百分比時候 設置成100 km時候 是1000 currencyFormat.setMultiplier(100); System.out.println(currencyFormat.format(0.912345)); } catch (Exception e) { e.printStackTrace(); }
運行結果:
整數(shù)格式
因為它很簡單,作用就是只解析 整數(shù)部分的。小數(shù)部分的會被舍入。
例如 “3456.78”→3456(并且在索引6之后保留解析位置)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/a1064072510/article/details/89887633