Java数字格式:DecimalFormat
在Java Numeric Formatting一文中 ,我描述并演示了NumberFormat静态方法提供的一些有用实例,例如NumberFormat.getNumberInstance(Locale) , NumberFormat.getPercentInstance(Locale) , NumberFormat.getCurrencyInstance(Locale)和NumberFormat.getIntegerInstance(Locale) ) 。 事实证明,所有这些抽象NumberFormat
实例实际上都是DecimalFormat实例,它扩展了NumberFormat
。
下一个代码清单和相关的输出展示了NumberFormat
的“ getInstance”方法返回的所有实例实际上都是DecimalFormat
实例。 区分同一DecimalFormat
类的这些实例的是它们的属性的设置,例如最小和最大整数数字(小数点左边的数字)以及小数位数的最小和最大数目(小数点右边的数字) 。 它们都共享相同的舍入模式和货币设置。
NumberFormat.getInstance()提供的实例是DecimalFormat实例
/** * Write characteristics of provided Currency object to * standard output. * * @param currency Instance of Currency whose attributes * are to be written to standard output. */ public void printCurrencyCharacteristics(final Currency currency) { out.print("\tCurrency: " + currency.getCurrencyCode() + "(ISO 4217 Code: " + currency.getNumericCode() + "), "); out.println(currency.getSymbol() + ", (" + currency.getDisplayName() + ")"); } /** * Writes characteristics of provided NumberFormat instance * to standard output under a heading that includes the provided * description. * * @param numberFormat Instance of NumberFormat whose key * characteristics are to be written to standard output. * @param description Description to be included in standard * output. */ public void printNumberFormatCharacteristics( final NumberFormat numberFormat, final String description) { out.println(description + ": " + numberFormat.getClass().getCanonicalName()); out.println("\tRounding Mode: " + numberFormat.getRoundingMode()); out.println("\tMinimum Fraction Digits: " + numberFormat.getMinimumFractionDigits()); out.println("\tMaximum Fraction Digits: " + numberFormat.getMaximumFractionDigits()); out.println("\tMinimum Integer Digits: " + numberFormat.getMinimumIntegerDigits()); out.println("\tMaximum Integer Digits: " + numberFormat.getMaximumIntegerDigits()); printCurrencyCharacteristics(numberFormat.getCurrency()); if (numberFormat instanceof DecimalFormat) { final DecimalFormat decimalFormat = (DecimalFormat) numberFormat; out.println("\tPattern: " + decimalFormat.toPattern()); } } /** * Display key characteristics of the "standard" * NumberFormat/DecimalFormat instances returned by the static * NumberFormat methods getIntegerInstance(), getCurrencyInstance(), * getPercentInstance(), and getNumberInstance(). */ public void demonstrateDecimalFormatInstancesFromStaticNumberFormatMethods() { final NumberFormat integerInstance = NumberFormat.getIntegerInstance(); printNumberFormatCharacteristics(integerInstance, "IntegerInstance"); final NumberFormat currencyInstance = NumberFormat.getCurrencyInstance(); printNumberFormatCharacteristics(currencyInstance, "CurrencyInstance"); final NumberFormat percentInstance = NumberFormat.getPercentInstance(); printNumberFormatCharacteristics(percentInstance, "PercentInstance"); final NumberFormat numberInstance = NumberFormat.getNumberInstance(); printNumberFormatCharacteristics(numberInstance, "NumberInstance"); }
尽管我的上一篇和到目前为止的文章已经演示了通过静态NumberFormat
访问方法获取DecimalFormat
实例,但是DecimalFormat
还具有三个重载的构造函数DecimalFormat() , DecimalFormat(String)和DecimalFormat(String,DecimalFormatSymbols) 。 但是请注意, DecimalFormat的Javadoc文档中有一条警告,指出“通常,请勿直接调用DecimalFormat构造函数,因为NumberFormat工厂方法可能返回DecimalFormat以外的子类。” 尽管有Javadoc警告,但我接下来的几个示例仍使用其直接构造函数实例化DecimalFormat
实例,因为这样做不会造成任何危害。
DecimalFormat
实例在很大程度上控制十进制数的表示格式。 下面的代码针对各种不同的自定义模式运行在先前示例中使用的标准数字集。 代码清单后的屏幕快照显示了应用这些模式时如何呈现这些数字。
/** * Apply provided pattern to DecimalFormat instance and write * output of application of that DecimalFormat instance to * standard output along with the provided description. * * @param pattern Pattern to be applied to DecimalFormat instance. * @param description Description of pattern being applied. */ private void applyPatternToStandardSample( final String pattern, final String description) { final DecimalFormat decimalFormat = new DecimalFormat(pattern); printHeader(description + " - Applying Pattern '" + pattern + "'"); for (final double theDouble : ourStandardSample) { out.println( theDouble + ": " + decimalFormat.format(theDouble)); } } /** * Demonstrate various String-based patters applied to * instances of DecimalFormat. */ public void demonstrateDecimalFormatPatternStringConstructor() { final String sixFixedDigitsPattern = "000000"; applyPatternToStandardSample(sixFixedDigitsPattern, "Six Fixed Digits"); final String sixDigitsPattern = "###000"; applyPatternToStandardSample(sixDigitsPattern, "Six Digits Leading Zeros Not Displayed"); final String percentagePattern = ""; applyPatternToStandardSample(percentagePattern, "Percentage"); final String millePattern = "\u203000"; applyPatternToStandardSample(millePattern, "Mille"); final String currencyPattern = "\u00A4"; applyPatternToStandardSample(currencyPattern, "Currency"); final String internationalCurrencyPattern = "\u00A4"; applyPatternToStandardSample(internationalCurrencyPattern, "Double Currency"); final String scientificNotationPattern = "0.###E0"; applyPatternToStandardSample(scientificNotationPattern, "Scientific Notation"); }
================================================================== = Six Fixed Digits - Applying Pattern '000000' ================================================================== NaN: 0.25: 000000 0.4: 000000 0.567: 000001 1.0: 000001 10.0: 000010 100.0: 000100 1000.0: 001000 10000.0: 010000 100000.0: 100000 1000000.0: 1000000 1.0E7: 10000000 Infinity: ∞ ================================================================== = Six Digits Leading Zeros Not Displayed - Applying Pattern '###000' ================================================================== NaN: 0.25: 000 0.4: 000 0.567: 001 1.0: 001 10.0: 010 100.0: 100 1000.0: 1000 10000.0: 10000 100000.0: 100000 1000000.0: 1000000 1.0E7: 10000000 Infinity: ∞ ================================================================== = Percentage - Applying Pattern '' ================================================================== NaN: 0.25: %25 0.4: %40 0.567: %57 1.0: %100 10.0: %1000 100.0: %10000 1000.0: %100000 10000.0: %1000000 100000.0: %10000000 1000000.0: %100000000 1.0E7: %1000000000 Infinity: %∞ ================================================================== = Mille - Applying Pattern '‰00' ================================================================== NaN: 0.25: ‰250 0.4: ‰400 0.567: ‰567 1.0: ‰1000 10.0: ‰10000 100.0: ‰100000 1000.0: ‰1000000 10000.0: ‰10000000 100000.0: ‰100000000 1000000.0: ‰1000000000 1.0E7: ‰10000000000 Infinity: ‰∞ ================================================================== = Currency - Applying Pattern '¤' ================================================================== NaN: 0.25: $0 0.4: $0 0.567: $1 1.0: $1 10.0: $10 100.0: $100 1000.0: $1000 10000.0: $10000 100000.0: $100000 1000000.0: $1000000 1.0E7: $10000000 Infinity: $∞ ================================================================== = Double Currency - Applying Pattern '¤' ================================================================== NaN: 0.25: $0 0.4: $0 0.567: $1 1.0: $1 10.0: $10 100.0: $100 1000.0: $1000 10000.0: $10000 100000.0: $100000 1000000.0: $1000000 1.0E7: $10000000 Infinity: $∞ ================================================================== = Scientific Notation - Applying Pattern '0.###E0' ================================================================== NaN: 0.25: 2.5E-1 0.4: 4E-1 0.567: 5.67E-1 1.0: 1E0 10.0: 1E1 100.0: 1E2 1000.0: 1E3 10000.0: 1E4 100000.0: 1E5 1000000.0: 1E6 1.0E7: 1E7 Infinity: ∞
对于最后两个应用DecimalFormat
示例,我将通过使用NumberFormat.getInstance(Locale)的首选方法来获取DecimalFormat
的实例。 第一个代码清单演示了应用于同一double的不同语言环境,然后演示了每种语言的输出格式。
/** * Provides an instance of DecimalFormat based on the provided instance * of Locale. * * @param locale Locale to be associated with provided instance of * DecimalFormat. * @return Instance of DecimalFormat associated with provided Locale. * @throws ClassCastException Thrown if the object provided to me * by NumberFormat.getCurrencyInstance(Locale) is NOT an instance * of class {@link java.text.DecimalFormat}. */ private DecimalFormat getDecimalFormatWithSpecifiedLocale(final Locale locale) { final NumberFormat numberFormat = NumberFormat.getCurrencyInstance(locale); if (!(numberFormat instanceof DecimalFormat)) { throw new ClassCastException( "NumberFormat.getCurrencyInstance(Locale) returned an object of type " + numberFormat.getClass().getCanonicalName() + " instead of DecimalFormat."); } return (DecimalFormat) numberFormat; } /** * Demonstrate formatting of double with various Locales. */ public void demonstrateDifferentLocalesCurrencies() { final double monetaryAmount = 14.99; out.println("Locale-specific currency representations of " + monetaryAmount + ":"); out.println("\tLocale.US: " + getDecimalFormatWithSpecifiedLocale(Locale.US).format(monetaryAmount)); out.println("\tLocale.UK: " + getDecimalFormatWithSpecifiedLocale(Locale.UK).format(monetaryAmount)); out.println("\tLocale.ENGLISH: " + getDecimalFormatWithSpecifiedLocale(Locale.ENGLISH).format(monetaryAmount)); out.println("\tLocale.JAPAN: " + getDecimalFormatWithSpecifiedLocale(Locale.JAPAN).format(monetaryAmount)); out.println("\tLocale.GERMANY: " + getDecimalFormatWithSpecifiedLocale(Locale.GERMANY).format(monetaryAmount)); out.println("\tLocale.CANADA: " + getDecimalFormatWithSpecifiedLocale(Locale.CANADA).format(monetaryAmount)); out.println("\tLocale.CANADA_FRENCH: " + getDecimalFormatWithSpecifiedLocale(Locale.CANADA_FRENCH).format(monetaryAmount)); out.println("\tLocale.ITALY: " + getDecimalFormatWithSpecifiedLocale(Locale.ITALY).format(monetaryAmount)); }
Locale-specific currency representations of 14.99: Locale.US: $14.99 Locale.UK: £14.99 Locale.ENGLISH: ¤14.99 Locale.JAPAN: ¥15 Locale.GERMANY: 14,99 € Locale.CANADA: $14.99 Locale.CANADA_FRENCH: 14,99 $ Locale.ITALY: € 14,99
到目前为止,我的DecimalFormat
示例专注于格式化表示的数字。 最后一个示例是另一个方向,并从字符串表示形式解析值。
/** * Demonstrate parsing. */ public void demonstrateParsing() { final NumberFormat numberFormat = NumberFormat.getCurrencyInstance(Locale.US); final double value = 23.23; final String currencyRepresentation = numberFormat.format(value); out.println("Currency representation of " + value + " is " + currencyRepresentation); try { final Number parsedValue = numberFormat.parse(currencyRepresentation); out.println("Parsed value of currency representation " + currencyRepresentation + " is " + parsedValue); } catch (ParseException parseException) { out.println("Exception parsing " + currencyRepresentation + parseException); } }
Currency representation of 23.23 is $23.23 Parsed value of currency representation $23.23 is 23.23
所示的最后一个示例实际上不需要访问具体的DecimalNumber
方法,并且能够仅使用NumberFormat
通告的方法。 本示例使用NumberFormat.format(double)格式化货币表示形式,然后解析提供的货币表示形式以使用NumberFormat.parse(String)返回原始值。
NumberFormat
,尤其是DoubleFormat
,“格式化和解析任何语言环境的数字”。
翻译自: https://www.javacodegeeks.com/2015/08/java-numeric-formatting-decimalformat.html