NumberFormat and DecimalFormat in Java
NumberFormat and DecimalFormat, in the java.text package, are used to format numbers as text for people to read, and to parse such text back into numbers. NumberFormat gives ready-made formats for a locale (a country and language): plain numbers with grouping, currencies and percentages. DecimalFormat lets you write your own pattern, such as #,##0.00. In this lesson, you will learn both, and finish with a small program that times a sort and prints the result neatly.
NumberFormat Factory Methods
| Method | Description |
|---|---|
NumberFormat.getInstance(locale) | It is used to format plain numbers with the locale's grouping. |
NumberFormat.getCurrencyInstance(locale) | It formats money with the locale's currency symbol. |
NumberFormat.getPercentInstance(locale) | It formats 0.25 as "25%". |
NumberFormat.getCompactNumberInstance(locale, style) | It formats 1200 as "1K" (Java 12). |
setMaximumFractionDigits(n) / setMinimumFractionDigits(n) | It controls the number of decimal places. |
parse(String) | It turns formatted text back into a Number. |
Example: Formatting for Different Locales
Let's see an example that formats the same amount in two locales.
import java.text.NumberFormat;
import java.util.Locale;
public class Locales {
public static void main(String[] args) {
double amount = 1234567.891;
Locale india = Locale.of("en", "IN");
System.out.println(
NumberFormat.getInstance(Locale.US).format(amount));
System.out.println(
NumberFormat.getInstance(Locale.GERMANY).format(amount));
System.out.println(
NumberFormat.getCurrencyInstance(india).format(amount));
System.out.println(
NumberFormat.getCurrencyInstance(Locale.US).format(amount));
System.out.println(
NumberFormat.getPercentInstance(Locale.US).format(0.856));
NumberFormat compact = NumberFormat.getCompactNumberInstance(
Locale.US, NumberFormat.Style.SHORT);
System.out.println(compact.format(1_250_000));
}
}1,234,567.891
1.234.567,891
₹1,234,567.89
$1,234,567.89
86%
1MExplanation: The US locale uses a comma to group thousands and a dot for decimals; the German locale does the opposite. Currency formats add the right symbol, such as ₹ for India, and round to two decimals. (Java's number formats group digits in threes, so they don't produce the Indian lakh grouping such as 12,34,567.) The percent format multiplies by 100 and rounds. The compact format shortens large numbers.
DecimalFormat Patterns
| Symbol | Meaning |
|---|---|
0 | A digit, shown even if it's zero |
# | A digit, hidden if it's a leading or trailing zero |
, | Grouping separator |
. | Decimal point |
% | Multiply by 100 and show as a percentage |
'text' | Literal text |
Example: Custom Patterns
import java.text.DecimalFormat;
public class Patterns {
public static void main(String[] args) {
double[] values = {5, 1234.5, 0.756};
DecimalFormat money = new DecimalFormat("#,##0.00");
DecimalFormat compact = new DecimalFormat("#.##");
DecimalFormat padded = new DecimalFormat("00000");
DecimalFormat percent = new DecimalFormat("0.0%");
for (double v : values) {
System.out.println(money.format(v) + " | " + compact.format(v)
+ " | " + padded.format(v) + " | " + percent.format(v));
}
}
}5.00 | 5 | 00005 | 500.0%
1,234.50 | 1234.5 | 01234 | 123450.0%
0.76 | 0.76 | 00001 | 75.6%Explanation: #,##0.00 always shows two decimals and groups thousands. #.## shows up to two decimals and drops trailing zeros. 00000 pads to five digits (rounding 1234.5 to the even neighbor, 1234, and 0.756 up to 1). 0.0% multiplies by 100.
The Checkpoint: Timing a Sort
This program times sorting arrays of different sizes with System.nanoTime and prints the results with DecimalFormat. Times depend on the computer, so the output is a sample.
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Random;
public class SortTimer {
public static void main(String[] args) {
DecimalFormat count = new DecimalFormat("#,##0");
DecimalFormat millis = new DecimalFormat("0.00");
Random random = new Random(1);
for (int size : new int[] {10_000, 100_000, 1_000_000}) {
int[] data = random.ints(size).toArray();
long start = System.nanoTime();
Arrays.sort(data);
double ms = (System.nanoTime() - start) / 1_000_000.0;
System.out.println("Sorted " + count.format(size)
+ " numbers in " + millis.format(ms) + " ms");
}
}
}Sorted 10,000 numbers in 2.96 ms
Sorted 100,000 numbers in 5.66 ms
Sorted 1,000,000 numbers in 44.42 msExplanation: For each size, a seeded Random fills an array, nanoTime is read before and after Arrays.sort, and the difference is converted to milliseconds. #,##0 adds grouping to the counts, and 0.00 shows exactly two decimals for the times.
Common Mistakes
Formatting money with double arithmetic. Calculate with BigDecimal, then format.
Sharing one DecimalFormat between threads. It isn't thread-safe; create one per thread or per use.
Forgetting the locale. The output then depends on the computer's settings.
Practice
- Easy: Print a list of product prices as Indian rupee amounts using
getCurrencyInstance(Locale.of("en", "IN")). - Harder: Parse the text "1,234,567.50" with an Indian
NumberFormat, add 10%, and print it again in the same format.
Key Takeaways
Was this tutorial helpful?