Formatting numbers in Java: DecimalFormat

Hello! Well, the Java Developer course in its new format starts quite well today, we are now preparing for the next launch a new format of utilities that will be divided into different levels and refined for different requests. In the meantime, let's look at what we have left of our stocks and look at using DecimalFormat to control the representation of numbers.

Go.

All the code provided below shows that the instances that the NumberFormat “getInstance” returns are actually DecimalFormat instances. They are distinguished from similar instances of the DecimalFormat class by attribute settings, for example, minimum / maximum integer values ​​(to the left of the decimal point) and minimum / maximum of fractional values ​​(to the right of the decimal point). They all have the same rounding mode and currency settings.



The instances provided by NumberFormat.getInstance () are DecimalFormat instances.

/** *     Currency *    . * * @param currency  Currency,   *       */ public void printCurrencyCharacteristics(final Currency currency) { out.print("\tCurrency: " + currency.getCurrencyCode() + "(ISO 4217 Code: " + currency.getNumericCode() + "), "); out.println(currency.getSymbol() + ", (" + currency.getDisplayName() + ")"); } /** *     *      ,   * . * * @param numberFormat  NumberFormat,   *        . * @param description ,      *  . */ 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()); } } /** *    “” * NumberFormat/DecimalFormat ,   * NumberFormat  getIntegerInstance(), getCurrencyInstance(), * getPercentInstance()  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"); } 




Although my last post and the entire beginning of this post demonstrate getting DecimalFormat instances through static NumberFormat methods, there are three overloaded DecimalFormat () , DecimalFormat (String) and DecimalFormat (String, DecimalFormatSymbols) constructors in DecimalFormat . However, it is worth noting that the DecimalFormat's Javadoc documentation has a warning: “As a rule, you should not call DecimalFormat constructors directly, since the NumberFormat factory methods can return subclasses other than DecimalFormat.” Despite the Javadoc warning, my following examples illustrate DecimalFormat instances their direct constructors. In our case, there is no reason not to.

DecimalFormat DecimalFormat maintain a high level of control over the formatting of decimal numbers. The following code skips the standard set of numbers used in the previous example through various custom patterns. The screenshot after the code clearly shows how these numbers are displayed in each of the examples.

 /** *      DecimalFormat   *         . * * * @param pattern      Decimal Format * @param description   . */ 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)); } } /** *   string-based ,   *  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: ∞ 

In the last two examples of using DecimalFormat I get a DecimalFormat instance using NumberFormat.getInstance (Locale) . The first code snippet shows the different localizations applied to one double precision number and the output format for each of them.

 /** *   DecimalFormat     * * @param locale      * DecimalFormat. * @return  DecimalFormat,    . * @throws ClassCastException Thrown,  ,   * NumberFormat.getCurrencyInstance(Locale)    *  {@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; } /** *        . */ 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)); } 

Regional Currency Representations 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 

Up to this point, all DecimalFormat examples focused on formatting numbers for a presentation. The final example goes in the opposite direction and parses the value from the string representation:

 /** *   */ 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 

In the last example, there was no need to access specific DecimalNumbers methods; it was enough to use the NumberFormat methods. Currencies are formatted using NumberFormat.format (double) , and then parsed to the original value with NumberFormat.parse (String) .

NumberFormat , to be exact DoubleFormat , “format and parse the values ​​for any localization.”

Source: https://habr.com/ru/post/415521/


All Articles