W3docs

Как форматировать числа в Java

Форматирование чисел в Java с помощью String.format, printf, DecimalFormat и NumberFormat.

Java предоставляет несколько способов превратить сырой int, double или BigDecimal в удобную для человека строку: разделители тысяч, фиксированное количество десятичных знаков, символы валюты и проценты. В этой главе рассматриваются наиболее часто используемые инструменты: String.format/printf, DecimalFormat и NumberFormat с поддержкой локали. Информацию об используемых числовых типах см. в разделе Java Numbers; полный список преобразований printf см. в разделе Java String Formatting.

Быстрое форматирование с String.format и printf

Для разового форматирования в строке лога или System.out форматная строка — самый лаконичный подход. printf выводит значение напрямую; String.format возвращает строку, которую можно сохранить.

double price = 1234.5;
System.out.printf("%.2f%n", price);        // 1234.50
String s = String.format("%,.2f", price);  // 1,234.50
System.out.println(String.format("%08.2f", 42.5)); // 00042.50

Спецификатор %.2f фиксирует два знака после запятой, флаг , добавляет разделители групп разрядов, а %08.2f дополняет поле нулями до ширины 8. Используйте %n вместо \n для корректного разрыва строки на любой платформе. Разделитель групп зависит от локали по умолчанию, поэтому тот же код может выводить 1.234,50 на машине с немецкой локалью.

Пользовательские шаблоны с DecimalFormat

Когда нужен полный контроль над шаблоном или требуется форматировать множество значений одним переиспользуемым объектом, используйте DecimalFormat. Вывод описывается шаблоном из символов # (необязательная цифра) и 0 (обязательная цифра).

DecimalFormat df = new DecimalFormat("#,##0.00");
df.format(1234.5);   // "1,234.50"
df.format(0.5);      // "0.50"

DecimalFormat sci = new DecimalFormat("0.###E0");
sci.format(123456);  // "1.235E5"

По умолчанию DecimalFormat использует режим округления RoundingMode.HALF_EVEN, что может удивить (2.5 округляется до 2). Установите df.setRoundingMode(RoundingMode.HALF_UP), если вам нужно привычное «округление половины вверх». Один экземпляр DecimalFormat не является потокобезопасным, поэтому создавайте по одному на каждый поток или используйте синхронизацию.

Валюта и проценты с учётом локали

Для валюты и процентов не стройте шаблон вручную. Фабричные методы NumberFormat выбирают правильный символ, разделители и количество знаков для заданной Locale.

NumberFormat us = NumberFormat.getCurrencyInstance(Locale.US);
us.format(1234.5);   // "$1,234.50"

NumberFormat pct = NumberFormat.getPercentInstance(Locale.US);
pct.format(0.87);    // "87%"

Обратите внимание: форматтер процентов умножает значение на 100, поэтому передаётся 0.87, чтобы получить 87%. Указание правильной Locale обеспечивает корректный вывод для каждого рынка.

ПодходЛучше всего дляУчёт локалиПереиспользование
printf / String.formatразовый выводда (локаль по умолчанию)нет
DecimalFormatпользовательские шаблоны, массовое форматированиеда (настраивается)да (не потокобезопасен)
NumberFormat.getCurrencyInstanceденьгидада
NumberFormat.getPercentInstanceдолидада

Полный выполняемый пример

Программа ниже форматирует одно и то же число четырьмя разными способами, а затем демонстрирует дополнение нулями, чтобы можно было сравнить результаты рядом.

java— editable, runs on the server

Что можно узнать из результата выполнения:

  • printf с %,.2f выводит 1,234,567.89, добавляя разделители групп и фиксируя два знака после запятой.
  • DecimalFormat("#,##0.00") даёт тот же результат 1,234,567.89, но в виде переиспользуемой возвращаемой строки.
  • getCurrencyInstance(Locale.US) добавляет символ $, выдавая $1,234,567.89.
  • getPercentInstance умножает 0.8736 на 100 и округляет до 87%.
  • %08.2f дополняет 42.5 нулями до ширины 8, выводя 00042.50.

Практика

Практика
Какой вызов форматирует double 0.87 как строку '87%'?
Какой вызов форматирует double 0.87 как строку '87%'?
Was this page helpful?