Java格式轉(zhuǎn)換
java.text.Format
Format是一個(gè)用于格式化語(yǔ)言環(huán)境敏感的信息(如日期、消息和數(shù)字)的抽象基類,直接已知子類有DateFormat, MessageFormat, NumberFormat。
Format定義了編程接口,用于將語(yǔ)言環(huán)境敏感的對(duì)象格式化為String(使用format方法)和將String重新解析為對(duì)象(使用 parseObject方法)。?
通常,一個(gè)Format的parseObject方法必須能解析任何由其Format方法格式化的字符串。不過(guò),也可能存在不能解析的異常情況。例如,F(xiàn)ormat方法可能創(chuàng)建中間無(wú)分隔符的兩個(gè)相鄰整數(shù),在這種情況下,parseObject無(wú)法判斷哪個(gè)數(shù)字屬于哪個(gè)數(shù)。
Java平臺(tái)為格式化日期、消息和數(shù)字分別提供了三個(gè)特殊的Format的子類:DateFormat、MessageFormat和NumberFormat。具體的子類必須實(shí)現(xiàn)三個(gè)方法:?
format(Object obj, StringBuffer toAppendTo, FieldPosition pos)?
formatToCharacterIterator(Object obj)?
parseObject(String source, ParsePosition pos)?
這些常規(guī)方法允許對(duì)對(duì)象進(jìn)行多態(tài)解析和格式化,還可以被使用(如被 MessageFormat 使用)。子類通常也為特定的輸入類型提供了另外的format方法,也為特定的結(jié)果類型提供了parse方法。當(dāng)在輸入文本的開(kāi)始沒(méi)有任何所需格式的文本時(shí),則任何不帶 ParsePosition參數(shù)的parse方法都應(yīng)該拋出ParseException。?
大多數(shù)子類還將實(shí)現(xiàn)以下工廠方法:?
getInstance 獲取一個(gè)適合于當(dāng)前語(yǔ)言環(huán)境的有用的格式對(duì)象?
getInstance(Locale) 獲取一個(gè)適合于指定語(yǔ)言環(huán)境的有用的格式對(duì)象。?
此外,某些子類還可能為了更特殊的控制實(shí)現(xiàn)其它getXxxxInstance方法。例如,NumberFormat類提供了getPercentInstance和 getCurrencyInstance方法來(lái)獲取特殊的數(shù)字格式器。
Format的子類如果允許程序員能為不同語(yǔ)言環(huán)境(比如用getInstance(Locale) )創(chuàng)建對(duì)象,必須實(shí)現(xiàn)以下類方法:?
public static Locale[] getAvailableLocales()
最后子類定義一個(gè)常量集合來(lái)標(biāo)識(shí)格式輸出中的不同字段。這些常量用于創(chuàng)建一個(gè)FieldPosition對(duì)象該對(duì)象標(biāo)識(shí)字段中所包含的信息及其在格式化結(jié)果中的位置。這些常量應(yīng)當(dāng)命名為item_FIELD,其中item標(biāo)識(shí)了該字段。有關(guān)這些常量的例子,請(qǐng)參閱 ERA_FIELD及其在DateFormat中的同類。
格式通常不是同步的。建議為每個(gè)線程創(chuàng)建獨(dú)立的格式實(shí)例。如果多個(gè)線程同時(shí)訪問(wèn)一個(gè)格式,其它必須保持外部同步。
java.text.FieldPosition
構(gòu)造方法
public FieldPosition(int field)
為給定字段創(chuàng)建一個(gè)FieldPosition對(duì)象。字段由常量標(biāo)識(shí),在不同的Format子類中,常量名稱一般以_FIELD結(jié)尾。
public FieldPosition(Format.Field attribute)
為給定的字段常量創(chuàng)建一個(gè)FieldPosition對(duì)象。字段由不同F(xiàn)ormat子類中定義的常量來(lái)標(biāo)識(shí)。這等效于調(diào)用new FieldPosition(attribute, -1)。
public FieldPosition(Format.Field attribute,int fieldID)
為給定的字段創(chuàng)建一個(gè)FieldPosition對(duì)象。字段由來(lái)自Field的子類之一的屬性常量以及一個(gè)由Format的子類定義的整型字段ID標(biāo)識(shí)。
當(dāng)attribute不為null時(shí),需要使用Field的Format子類應(yīng)當(dāng)優(yōu)先考慮attribute而忽略fieldID。
不過(guò),舊的Format子類可能不知道Field而依靠fieldID。如果該字段沒(méi)有相應(yīng)的整型常量,則fieldID應(yīng)為-1。
FieldPosition是Format及其子類用于在格式輸出中(format(Object obj, StringBuffer toAppendTo, FieldPosition pos))標(biāo)識(shí)字段的簡(jiǎn)單類。
FieldPosition保持對(duì)格式輸出中字段位置的兩個(gè)索引進(jìn)行跟蹤:字段的第一個(gè)字符的索引和緊跟字段的最后一個(gè)字符的索引。?
new FieldPosition(NumberFormat.INTEGER_FIELD);
stringBuffer1 = 1.235
?INTEGER:beginIndex=0,endIndex=1???? //索引位0-1(跟蹤索引位)
new FieldPosition(NumberFormat.FRACTION_FIELD);
stringBuffer2 = 1.235
FRACTION:beginIndex=2,endIndex=5?? //索引位2-5(跟蹤索引位)
不同的Format類中的format方法需要一個(gè)FieldPosition對(duì)象作為參數(shù)。使用此format方法執(zhí)行部分格式化或者以獲取格式化輸出的信息(比如字段位置)。字段可以通過(guò)兩種方式標(biāo)識(shí),兩者的作用是一致的,只是Format.Field常量更詳細(xì),建議使用這種方式:?
1、通過(guò)一個(gè)其名稱通常以_FIELD結(jié)尾的整型常量。這些常量在Format的不同子類中定義:?
NumberFormat
static int FRACTION_FIELD
? ? ? ? ? 用于構(gòu)造FieldPosition對(duì)象的字段常量。
static int INTEGER_FIELD
? ? ? ? ? 用于構(gòu)造FieldPosition對(duì)象的字段常量。
總結(jié):二者的跟蹤的索引位不同
例子:
public static void main(String[] args) {
????????//建立一個(gè)數(shù)字格式化對(duì)象
? ? ? ? NumberFormat numberFormat = NumberFormat.getInstance();
????????//建立字符數(shù)組緩沖器)—— 線程安全
? ? ? ? StringBuffer stringBuffer1 = new StringBuffer();
????????//數(shù)字格式化,用于格式化時(shí)對(duì)索引跟蹤(第一個(gè)字符的索引,緊跟字段最后一個(gè)字符的索引)
? ? ? ? FieldPosition fieldPosition = new FieldPosition(NumberFormat.INTEGER_FIELD);
????????//十進(jìn)位小數(shù)對(duì)象
? ? ? ? BigDecimal bigDecimal = new BigDecimal("1.23456789");
????????//執(zhí)行格式化
? ? ? ? stringBuffer1 = numberFormat.format(bigDecimal, stringBuffer1, fieldPosition);
? ? ? ? System.out.println("stringBuffer1 = " + stringBuffer1);? //結(jié)果為1.235
????????//獲取索引
? ? ? ? System.out.println("INTEGER:beginIndex=" + fieldPosition.getBeginIndex() + ",endIndex=" + fieldPosition.getEndIndex());
? ? ? ? fieldPosition = new FieldPosition(NumberFormat.FRACTION_FIELD);
? ? ? ? StringBuffer stringBuffer2 = new StringBuffer();
? ? ? ? stringBuffer2 = numberFormat.format(bigDecimal, stringBuffer2, fieldPosition);
? ? ? ? System.out.println("stringBuffer2 = " + stringBuffer2);
? ? ? ? System.out.println("FRACTION:beginIndex=" + fieldPosition.getBeginIndex() + ",endIndex=" + fieldPosition.getEndIndex());
? ? }
結(jié)果為:
stringBuffer1 = 1.235
??INTEGER:beginIndex=0,endIndex=1???? //索引位0-1
stringBuffer2 = 1.235
FRACTION:beginIndex=2,endIndex=5?? //索引位2-5
2、通過(guò)一個(gè)Format.Field常量:標(biāo)識(shí)要格式化的類型是什么?
NumberFormat.Field
static NumberFormat.Field CURRENCY
? ? ? ? ? 標(biāo)識(shí)貨幣字段的常量。
static NumberFormat.Field DECIMAL_SEPARATOR
? ? ? ? ? 標(biāo)識(shí)小數(shù)點(diǎn)字段的常量。
static NumberFormat.Field EXPONENT
? ? ? ? ? 標(biāo)識(shí)指數(shù)字段的常量。
static NumberFormat.Field EXPONENT_SIGN
? ? ? ? ? 標(biāo)識(shí)指數(shù)符號(hào) (exponent sign) 字段的常量。
static NumberFormat.Field EXPONENT_SYMBOL
? ? ? ? ? 標(biāo)識(shí)指數(shù)符號(hào) (exponent symbol) 字段的常量。
static NumberFormat.Field FRACTION
? ? ? ? ? 標(biāo)識(shí)小數(shù)字段的常量。
static NumberFormat.Field GROUPING_SEPARATOR
? ? ? ? ? 標(biāo)識(shí)組分隔符字段的常量。
static NumberFormat.Field INTEGER
? ? ? ? ? 標(biāo)識(shí)整數(shù)字段的常量。
static NumberFormat.Field PERCENT
? ? ? ? ? 標(biāo)識(shí)百分?jǐn)?shù)字段的常量。
static NumberFormat.Field PERMILLE
? ? ? ? ? 標(biāo)識(shí)千分?jǐn)?shù)字段的常量。
static NumberFormat.Field SIGN
? ? ? ? ? 標(biāo)識(shí)符號(hào)字段的常量。
? FieldPosition pos = new FieldPosition(DateFormat.Field.DAY_OF_MONTH);
????????? 標(biāo)識(shí)日期字段的常量
public static void main(String[] args) {
? ? ? ? NumberFormat numberFormat = NumberFormat.getInstance();
? ? ? ? StringBuffer stringBuffer1 = new StringBuffer();
? ? ? ? FieldPosition fieldPosition = new FieldPosition(NumberFormat.Field.INTEGER);
? ? ? ? BigDecimal bigDecimal = new BigDecimal("1.23456789");
? ? ? ? stringBuffer1 = numberFormat.format(bigDecimal, stringBuffer1, fieldPosition);
? ? ? ? System.out.println("stringBuffer1 = " + stringBuffer1);
? ? ? ? System.out.println("INTEGER:beginIndex=" + fieldPosition.getBeginIndex() + ",endIndex=" + fieldPosition.getEndIndex());
? ? ? ? fieldPosition = new FieldPosition(NumberFormat.Field.FRACTION);
? ? ? ? StringBuffer stringBuffer2 = new StringBuffer();
? ? ? ? stringBuffer2 = numberFormat.format(bigDecimal, stringBuffer2, fieldPosition);
? ? ? ? System.out.println("stringBuffer2 = " + stringBuffer2);
? ? ? ? System.out.println("FRACTION:beginIndex=" + fieldPosition.getBeginIndex() + ",endIndex=" + fieldPosition.getEndIndex());
? ? }
輸出結(jié)果:
stringBuffer1 = 1.235
INTEGER:beginIndex=0,endIndex=1
stringBuffer2 = 1.235
FRACTION:beginIndex=2,endIndex=5
public static void main(String[] args) {
? ? ? ? DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
? ? ? ? StringBuffer stringBuffer = new StringBuffer();
? ? ? ? FieldPosition pos = new FieldPosition(DateFormat.Field.DAY_OF_MONTH);
? ? ? ? stringBuffer = dateFormat.format(new Date(), stringBuffer, pos);
? ? ? ? System.out.println("stringBuffer = " + stringBuffer);
? ? ? ? System.out.println("DATE_FIELD:beginIndex= " + pos.getBeginIndex() + ",endIndex=" + pos.getEndIndex());
? ? }
輸出結(jié)果:
stringBuffer = 2016年6月28日 上午11時(shí)07分18秒
DATE_FIELD:beginIndex= 7,endIndex=9
java.text.ParsePosition
ParsePosition是Format及其子類所使用的簡(jiǎn)單類,用來(lái)在解析過(guò)程中跟蹤當(dāng)前位置。各種Format類中的parseObject方法要求將 ParsePosition對(duì)象作為一個(gè)變量。解析具有不同格式的字符串時(shí),可以使用同一個(gè)ParsePosition,因?yàn)樗饕齾?shù)記錄的是當(dāng)前位置。ParsePosition也會(huì)記錄解析錯(cuò)誤的位置。
構(gòu)造方法
public ParsePosition(int index)
創(chuàng)建一個(gè)具有給定初始索引的新 ParsePosition。
例子:
public static void main(String[] args) {
? ? ? ? SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
? ? ? ? String strings[] = {"xxx 2016-06-28 xxx1", "20160628 xxx2"};
? ? ? ? for (int i = 0; i < strings.length; i++) {
? ? ? ? ? ? ParsePosition parsePosition = new ParsePosition(4);//從第四位開(kāi)始處理
? ? ? ? ? ? Date date = simpleDateFormat.parse(strings[i], parsePosition);
? ? ? ? ? ? //解析錯(cuò)誤,返回null
? ? ? ? ? ? if (date == null) {
? ? ? ? ? ? ? ? System.out.println("無(wú)效日期:" + strings[i]);
? ? ? ? ? ? ? ? System.out.println("解析出錯(cuò)的索引=" + parsePosition.getErrorIndex());
? ? ? ? ? ? ? ? System.out.println("當(dāng)前索引=" + parsePosition.getIndex());
? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? }
? ? ? ? ? ? String substring = strings[i].substring(parsePosition.getIndex());
? ? ? ? ? ? System.out.println("日期=" + date + ",剩余部分:" + substring);
? ? ? ? }
? ? }
日期=Tue Jun 28 00:00:00 CST 2016,剩余部分: xxx1
無(wú)效日期:20160628 xxx2
解析出錯(cuò)的索引=8
當(dāng)前索引=4
java.text.NumberFormat
NumberFormat 是所有數(shù)值格式的抽象基類。此類提供格式化和解析數(shù)值的接口。NumberFormat 還提供了一些方法來(lái)確定哪些語(yǔ)言環(huán)境具有數(shù)值格式,以及它們的名稱是什么。?
NumberFormat 可用于格式化和解析任何語(yǔ)言環(huán)境的數(shù)值。使代碼能夠完全獨(dú)立于小數(shù)點(diǎn)、千位分隔符甚至所用特定小數(shù)位數(shù)的語(yǔ)言環(huán)境約定,并與數(shù)值格式是否為偶小數(shù)無(wú)關(guān)。
如何獲得一個(gè)實(shí)例?
NumberFormat總共有三種實(shí)例,常規(guī)數(shù)值、貨幣數(shù)值,百分比數(shù)值,每種都可以用默認(rèn)語(yǔ)言環(huán)境和指定語(yǔ)言環(huán)境。
常規(guī)數(shù)值:getInstance()(同getNumberInstance())、getInstance(Locale inLocale)(同getNumberInstance(Locale inLocale))
貨幣數(shù)值:getCurrencyInstance()、getCurrencyInstance(Locale inLocale)
百分比數(shù)值:getPercentInstance()、getPercentInstance(Locale inLocale)
public static Locale[] getAvailableLocales()
返回一個(gè)當(dāng)前所支持的語(yǔ)言環(huán)境數(shù)組
void setCurrency(Currency currency)?
設(shè)置格式化貨幣值時(shí)此數(shù)值格式使用的貨幣。
void setGroupingUsed(boolean newValue)?
設(shè)置此格式中是否使用分組,即是否有千位分隔符(逗號(hào))。
void setMaximumFractionDigits(int newValue)?
設(shè)置數(shù)的小數(shù)部分所允許的最大位數(shù)。與解析無(wú)關(guān)。
void setMaximumIntegerDigits(int newValue)?
設(shè)置數(shù)的整數(shù)部分所允許的最大位數(shù)。與解析無(wú)關(guān)。
void setMinimumFractionDigits(int newValue)?
設(shè)置數(shù)的小數(shù)部分所允許的最小位數(shù)。與解析無(wú)關(guān)。
void setMinimumIntegerDigits(int newValue)?
設(shè)置數(shù)的整數(shù)部分所允許的最小位數(shù)。與解析無(wú)關(guān)。
void setParseIntegerOnly(boolean value)?
設(shè)置數(shù)是否應(yīng)該僅作為整數(shù)進(jìn)行解析。與格式化無(wú)關(guān)。
例子:
public static void main(String[] args) throws Exception {
? ? ? ? //常規(guī)數(shù)值
? ? ? ? NumberFormat format1 = NumberFormat.getNumberInstance();
? ? ? ? System.out.println(format1.getMaximumIntegerDigits());//2147483647
? ? ? ? System.out.println(format1.getMinimumIntegerDigits());//1
? ? ? ? System.out.println(format1.getMaximumFractionDigits());//3
? ? ? ? System.out.println(format1.getMinimumFractionDigits());//0
? ? ? ? System.out.println(format1.isGroupingUsed());//true
? ? ? ? System.out.println(format1.isParseIntegerOnly());//false
? ? ? ? System.out.println(format1.format(10000000));//10,000,000 默認(rèn)分組
? ? ? ? System.out.println(format1.format(10000000.000));//10,000,000 小數(shù)點(diǎn)后全身0,被舍棄
? ? ? ? System.out.println(format1.format(10000000.001));//10,000,000.001
? ? ? ? System.out.println(format1.format(10000000.0001));//10,000,000 默認(rèn)最大小數(shù)位數(shù)是3位
? ? ? ? System.out.println(format1.parse("10000000.001"));//1.0000000001E7 默認(rèn)可以解析小數(shù)
? ? ? ? format1.setParseIntegerOnly(true);
? ? ? ? System.out.println(format1.parse("10000000.001"));//10000000
? ? ? ? //百分比數(shù)值
? ? ? ? NumberFormat format2 = NumberFormat.getPercentInstance();
? ? ? ? System.out.println(format2.getMaximumIntegerDigits());//2147483647
? ? ? ? System.out.println(format2.getMinimumIntegerDigits());//1
? ? ? ? System.out.println(format2.getMaximumFractionDigits());//0
? ? ? ? System.out.println(format2.getMinimumFractionDigits());//0
? ? ? ? System.out.println(format2.isGroupingUsed());//true
? ? ? ? System.out.println(format2.isParseIntegerOnly());//false
? ? ? ? System.out.println(format2.format(1.01));//101%
? ? ? ? System.out.println(format2.format(1.001));//100% 默認(rèn)最大小數(shù)位數(shù)是0
? ? ? ? format2.setMaximumFractionDigits(1);
? ? ? ? System.out.println(format2.format(1.001));//100.1%
? ? ? ? System.out.println(format2.parse("100.1%"));// 1.001 默認(rèn)可以解析小數(shù)
? ? ? ? //貨幣格式
? ? ? ? NumberFormat format3 = NumberFormat.getCurrencyInstance();
? ? ? ? System.out.println(format3.getMaximumIntegerDigits());//2147483647
? ? ? ? System.out.println(format3.getMinimumIntegerDigits());//1
? ? ? ? System.out.println(format3.getMaximumFractionDigits());//2
? ? ? ? System.out.println(format3.getMinimumFractionDigits());//2
? ? ? ? System.out.println(format3.isGroupingUsed());//true
? ? ? ? System.out.println(format3.isParseIntegerOnly());//false
? ? ? ? System.out.println(format3.format(10000));//¥10,000.00 默認(rèn)語(yǔ)言環(huán)境是zh_CN
? ? ? ? System.out.println(format3.parse("¥10,000.00"));//10000
? ? }
java.text.DecimalFormat
DecimalFormat是NumberFormat的一個(gè)具體子類,用于格式化十進(jìn)制數(shù)字。該類設(shè)計(jì)有各種功能,使其能夠解析和格式化任意語(yǔ)言環(huán)境中的數(shù),包括對(duì)西方語(yǔ)言、阿拉伯語(yǔ)和印度語(yǔ)數(shù)字的支持。通常不直接調(diào)用DecimalFormat的構(gòu)造方法,要獲取具體語(yǔ)言環(huán)境的DecimalFormat(包括默認(rèn)語(yǔ)言環(huán)境),可調(diào)用NumberFormat的某個(gè)工廠方法,如getInstance()。如果看源碼會(huì)發(fā)現(xiàn)getInstance()其實(shí)返回的就是DecimalFormat實(shí)例,因?yàn)橐院蟮陌姹綨umberFormat的工廠方法可能返回不同于DecimalFormat的子類:?
NumberFormat f = NumberFormat.getInstance(loc);
if (f instanceof DecimalFormat) {
? ? ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true);
}
DecimalFormat包含一個(gè)模式和一組符號(hào)。可直接使用applyPattern()或間接使用API方法來(lái)設(shè)置模式。符號(hào)存儲(chǔ)在DecimalFormatSymbols象中。如果想要改變符號(hào),比如小數(shù)點(diǎn),可以使用和DecimalFormate關(guān)聯(lián)的DecimalFormatSymbols,此類表示了DecimalFormat格式化數(shù)字所需的符號(hào)集(如小數(shù)點(diǎn)、組分隔符等等)。DecimalFormat 根據(jù)其語(yǔ)言環(huán)境數(shù)據(jù)為其自身創(chuàng)建一個(gè)DecimalFormatSymbols實(shí)例。如果需要更改這些符號(hào),可從DecimalFormat#getDecimalFormatSymbols()獲得DecimalFormatSymbols對(duì)象并修改它。通常程序員不需要修改DecimalFormatSymbols。
特殊符號(hào)
0
數(shù)字。阿拉伯?dāng)?shù)字,如果當(dāng)前位置不存在數(shù)字,則顯示為0
#
數(shù)字。阿拉伯?dāng)?shù)字,在不影響數(shù)值的情況下,當(dāng)前位置如果為0或者不存在,則不顯示
.
數(shù)字。小數(shù)分隔符或貨幣小數(shù)分隔符
-
數(shù)字。減號(hào)
,
數(shù)字。分組分隔符
E
數(shù)字。分隔科學(xué)計(jì)數(shù)法中的尾數(shù)和指數(shù)。在前綴或后綴中無(wú)需加引號(hào)
;
子模式邊界。分隔正數(shù)和負(fù)數(shù)子模式
%
前綴或后綴。乘以 100 并顯示為百分?jǐn)?shù)
\u2030
前綴或后綴。乘以 1000 并顯示為千分?jǐn)?shù)
¤(\u00A4)
前綴或后綴。貨幣記號(hào),由貨幣符號(hào)替換。如果兩個(gè)同時(shí)出現(xiàn),則用國(guó)際貨幣符號(hào)替換。如果出現(xiàn)在某個(gè)模式中,則使用貨幣小數(shù)分隔符,而不使用小數(shù)分隔符
‘
前綴或后綴。用于在前綴或或后綴中為特殊字符加引號(hào),例如 "‘#‘#" 將 123 格式化為 "#123"。要?jiǎng)?chuàng)建單引號(hào)本身,請(qǐng)連續(xù)使用兩個(gè)單引號(hào):"# o‘‘clock"
語(yǔ)法
1、前綴和后綴:數(shù)字前后的符號(hào),除 \uFFFE、\uFFFF 和特殊字符以外的所有 Unicode 字符。
2、小數(shù)分隔符和千位分隔符應(yīng)該是不同的字符,否則將不可能進(jìn)行解析。
3、如果使用具有多個(gè)分組字符的模式,則最后一個(gè)分隔符和整數(shù)結(jié)尾之間的間隔才是使用的分組大小。所以 "#,##,###,####" == "######,####" == "##,####,####"。?
構(gòu)造方法
DecimalFormat()?
使用默認(rèn)模式和默認(rèn)語(yǔ)言環(huán)境的符號(hào)創(chuàng)建一個(gè)DecimalFormat。?
DecimalFormat(String pattern)?
使用給定的模式和默認(rèn)語(yǔ)言環(huán)境的符號(hào)創(chuàng)建一個(gè)DecimalFormat。?
DecimalFormat(String pattern, DecimalFormatSymbols symbols)?
使用給定的模式和符號(hào)創(chuàng)建一個(gè)DecimalFormat。?
例子:
public static void main(String[] args) throws Exception {
? ? ? ? DecimalFormatSymbols unusualSymbols = new DecimalFormatSymbols();
? ? ? ? unusualSymbols.setDecimalSeparator(‘|‘);
? ? ? ? unusualSymbols.setGroupingSeparator(‘^‘);
? ? ? ? String strange = "#,##0.###";
? ? ? ? DecimalFormat weirdFormatter = new DecimalFormat(strange, unusualSymbols);
? ? ? ? weirdFormatter.setGroupingSize(4);
? ? ? ? String bizarre = weirdFormatter.format(12345.678);
? ? ? ? System.out.println(bizarre);//1^2345|678
? ? }