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. public void printCurrencyCharacteristics(final Currency currency) { out.print("\tCurrency: " + currency.getCurrencyCode() + "(ISO 4217 Code: " + currency.getNumericCode() + "), "); out.println(currency.getSymbol() + ", (" + currency.getDisplayName() + ")"); } 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()); } } 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.
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)); } } 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.
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.”