Compact Number Formatting in Java

1. Introduction

In US locale, you may have seen 1000 written as “1k”, 1000000 as “1M”. Here, “1K” and “1M” are shorter or compact forms. A compact number formatting refers to the representation of a number in a shorter form, based on the patterns provided for a given locale. CompactNumberFormat is a concrete subclass of NumberFormat.

Compact number formatting is useful in the environment where the space is limited and the string can be displayed in limited space. It is defined by LDML’s specification for Compact Number Formats.

CompactNumberFormat for a locale can be get using one of the factory methods, For example, NumberFormat.getCompactNumberInstance(Locale, Style).

A number can be formatted in the compact forms with two different styles, SHORT and LONG. The LONG style for 10000 results in “10 thousand”.

CompactNumberFormat was added in Java 12.

2. Compact Number Patterns

Compact number patterns are displayed as a sequence of formats, with each format applying to a specific range of numbers. For instance, in the US locale, the SHORT style of compact number patterns includes: {“”, “”, “”, “0K”, “00K”, “000K”, “0M”, “00M”, “000M”, “0B”, “00B”, “000B”, “0T”, “00T”, “000T”}. These patterns cover numbers from 100 to 1014.
The number of patterns can vary, and each is assigned an index starting from 100. For instance, in the given patterns, the pattern at index 3 (“0K”) formats numbers between 1000 and 9999.

3. Formatting

By default, formatting returns a string without fractional digits. However, users can include the fractional part by using the setMinimumFractionDigits(int) method. For example, the number 1000.0 or 1000 is formatted as “1K” rather than “1.00K” in the US locale. Consequently, the formatting patterns only specify the minimum integer digits, along with any prefixes and/or suffixes, but do not include fractional digits.

4. Creating a CompactNumberFormat Instance

To create a CompactNumberFormat, use one of the factory methods given by NumberFormat.

NumberFormat fmt = NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.LONG); 
NumberFormat fmt = NumberFormat.getCompactNumberInstance(new Locale("hi", "IN"), NumberFormat.Style.SHORT);

5. Custom CompactNumberFormat Instance

We can also create a customized instance and define how the numbers will be represented in shorter form using CompactNumberFormat(String, DecimalFormatSymbols, String[]) constructor.

final String[] compactPatterns
            = {"", "", "", "0k", "00k", "000k", "0m", "00m", "000m",
                "0b", "00b", "000b", "0t", "00t", "000t"}; 

final DecimalFormat decimalFormat = (DecimalFormat) NumberFormat.getNumberInstance(Locale.GERMANY);

final CompactNumberFormat customCompactNumberFormat
            = new CompactNumberFormat( decimalFormat.toPattern(),
                                       decimalFormat.getDecimalFormatSymbols(),  compactPatterns);

6. Examples

6.1 Simple Formatting

Here, we are formatting the numbers first in the long and then in the short styles. We are using the US locale.

        NumberFormat fmt = NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.LONG);

        System.out.println( fmt.format(100) );
        System.out.println( fmt.format(1000) );
        System.out.println( fmt.format(10000) );
        System.out.println( fmt.format(100000) );

        NumberFormat fmtShort = NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);

        System.out.println( fmtShort.format(100) );
        System.out.println( fmtShort.format(1000) );
        System.out.println( fmtShort.format(10000) );
        System.out.println( fmtShort.format(100000) );


1 thousand
10 thousand
100 thousand

6.2 Set Fractional Number

        NumberFormat fmt = NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);

        System.out.println( fmt.format(10000) );
        System.out.println( fmt.format(10012) );
        System.out.println( fmt.format(100201) );
        System.out.println( fmt.format(1111111) );



6.3 Parsing a Given Compact Number

        NumberFormat fmt = NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.LONG);

        System.out.println( fmt.parse("100") );
        System.out.println( fmt.parse("1 thousand") );
        System.out.println( fmt.parse("10 thousand") );
        System.out.println( fmt.parse("100 thousand") );



7. Conclusion

CompactNumberFormat is a powerful tool for formatting large numbers in a readable, compact form. It supports various locales and can be customized to include fractional digits or to use different formatting styles. This makes it ideal for applications that need to present numerical data in a user-friendly manner.