Java форматирование вывода числа

Форматирование чисел в Java

В этом руководстве мы рассмотрим различные подходы к форматированию чисел в Java и способы их реализации.

2. Базовое форматирование чисел с помощью String#format ​

Метод String#format очень полезен для форматирования чисел. Метод принимает два аргумента. Первый аргумент описывает образец того, сколько знаков после запятой мы хотим видеть, а второй аргумент — заданное значение:

 double value = 4.2352989244d;   assertThat(String.format("%.2f", value)).isEqualTo("4.24");   assertThat(String.format("%.3f", value)).isEqualTo("4.235"); 

3. Десятичное форматирование путем округления​

В Java у нас есть два примитивных типа, которые представляют десятичные числа — float и decimal :

 double myDouble = 7.8723d;   float myFloat = 7.8723f; 

Количество знаков после запятой может быть разным в зависимости от выполняемых операций. В большинстве случаев нас интересуют только первые несколько знаков после запятой . Давайте рассмотрим некоторые способы форматирования десятичной дроби путем округления.

3.1. Использование BigDecimal для форматирования чисел​

Класс BigDecimal предоставляет методы для округления до указанного числа знаков после запятой. Давайте создадим вспомогательный метод, который будет возвращать двойное число, округленное до нужного числа разрядов:

 public static double withBigDecimal(double value, int places)    BigDecimal bigDecimal = new BigDecimal(value);   bigDecimal = bigDecimal.setScale(places, RoundingMode.HALF_UP);   return bigDecimal.doubleValue();   > 

Мы начинаем с нового экземпляра BigDecimal с нашим исходным десятичным значением. Затем, устанавливая масштаб, мы указываем желаемое количество знаков после запятой и то, как мы хотим округлить число . Использование этого метода позволяет нам легко форматировать двойное значение:

 double D = 4.2352989244d;   assertThat(withBigDecimal(D, 2)).isEqualTo(4.24);   assertThat(withBigDecimal(D, 3)).isEqualTo(4.235); 

3.2. Использование Math#round ​

Мы также можем воспользоваться статическими методами класса Math , чтобы округлить двойное значение до указанного десятичного разряда. В этом случае мы можем настроить количество знаков после запятой, умножив, а затем разделив на 10^n . Давайте проверим наш вспомогательный метод:

 public static double withMathRound(double value, int places)    double scale = Math.pow(10, places);   return Math.round(value * scale) / scale;   > 
 assertThat(withMathRound(D, 2)).isEqualTo(4.24);   assertThat(withMathRound(D, 3)).isEqualTo(4.235); 

Однако этот способ рекомендуется только в особых случаях, так как иногда вывод может округляться не так, как ожидалось перед печатью.

Это связано с тем, что Math#round усекает значение . Давайте посмотрим, как это может произойти:

 System.out.println(withMathRound(1000.0d, 17));   // Gives: 92.23372036854776 !!   System.out.println(withMathRound(260.775d, 2));   // Gives: 260.77 instead of expected 260.78 

Итак, метод указан только для учебных целей.

4. Форматирование различных типов чисел​

В некоторых конкретных случаях нам может понадобиться отформатировать число для определенного типа, такого как валюта, большое целое число или процент.

4.1. Форматирование больших целых чисел с помощью запятых​

Всякий раз, когда у нас есть большое целое число в нашем приложении, мы можем захотеть отобразить его с запятыми, используя DecimalFormat с предопределенным шаблоном:

 public static String withLargeIntegers(double value)    DecimalFormat df = new DecimalFormat("###,###,###");   return df.format(value);   >    int value = 123456789;   assertThat(withLargeIntegers(value)).isEqualTo("123,456,789"); 

4.2. Дополнение числа​

В некоторых случаях мы можем захотеть дополнить число нулями для заданной длины. Здесь мы можем использовать метод String#format , как описано ранее:

 public static String byPaddingZeros(int value, int paddingLength)    return String.format("%0" + paddingLength + "d", value);   >    int value = 1;   assertThat(byPaddingOutZeros(value, 3)).isEqualTo("001"); 

4.3. Форматирование чисел с двумя нулями после запятой​

Чтобы иметь возможность печатать любое заданное число с двумя нулями после запятой, мы будем использовать еще один класс DecimalFormat с предопределенным шаблоном:

 public static double withTwoDecimalPlaces(double value)    DecimalFormat df = new DecimalFormat("#.00");   return new Double(df.format(value));   >    int value = 12;   assertThat(withTwoDecimalPlaces(value)).isEqualTo(12.00); 

В данном случае мы создали новый формат с шаблоном, указывающим два нуля после запятой .

4.4. Форматирование и проценты​

Время от времени нам может понадобиться отображать проценты.

В этом случае мы можем использовать метод NumberFormat# getPercentInstance . Этот метод позволяет нам предоставить Locale для печати значения в формате, правильном для указанной вами страны:

 public static String forPercentages(double value, Locale locale)    NumberFormat nf = NumberFormat.getPercentInstance(locale);   return nf.format(value);   >    double value = 25f / 100f;   assertThat(forPercentages(value, new Locale("en", "US"))).isEqualTo("25%"); 

4.5. Форматирование номера валюты​

Обычный способ хранения валют в нашем приложении — использование BigDecimal . Что, если мы хотим отобразить их пользователю? В этом случае мы можем использовать класс NumberFormat :

 public static String currencyWithChosenLocalisation(double value, Locale locale)    NumberFormat nf = NumberFormat.getCurrencyInstance(locale);   return nf.format(value);   > 

Мы получаем экземпляр валюты для данной локали , а затем просто вызываем метод форматирования со значением. Результатом является число, отображаемое в качестве валюты для указанной страны:

 double value = 23_500;   assertThat(currencyWithChosenLocalisation(value, new Locale("en", "US"))).isEqualTo("$23,500.00");   assertThat(currencyWithChosenLocalisation(value, new Locale("zh", "CN"))).isEqualTo("¥23,500.00");   assertThat(currencyWithChosenLocalisation(value, new Locale("pl", "PL"))).isEqualTo("23 500 zł"); 

5. Варианты использования расширенного форматирования​

DecimalFormat — один из самых популярных способов форматирования десятичного числа в Java. Как и в предыдущих примерах, мы напишем вспомогательный метод:

 public static double withDecimalFormatLocal(double value)    DecimalFormat df = (DecimalFormat) NumberFormat.getNumberInstance(Locale.getDefault());   return new Double(df.format(value));   > 

Наш тип форматирования получит настройку по умолчанию для данной локализации.

Десятичное форматирование обрабатывается по-разному в разных странах, использующих свои системы счисления. Например, символ группировки (запятая в США, но пробел или точка в других регионах), размер группы (три в США и большинстве регионов, но разные в Индии) или десятичный символ (точка в США, но запятая в других регионах).

 double D = 4.2352989244d;   assertThat(withDecimalFormatLocal(D)).isEqualTo(4.235); 

Мы также можем расширить эту функциональность, чтобы предоставить некоторые определенные шаблоны:

 public static double withDecimalFormatPattern(double value, int places)    DecimalFormat df2 = new DecimalFormat("#,###,###,##0.00");   DecimalFormat df3 = new DecimalFormat("#,###,###,##0.000");   if (places == 2)   return new Double(df2.format(value));   else if (places == 3)   return new Double(df3.format(value));   else   throw new IllegalArgumentException();   >    assertThat(withDecimalFormatPattern(D, 2)).isEqualTo(4.24);   assertThat(withDecimalFormatPattern(D, 3)).isEqualTo(4.235); 

Здесь мы позволяем нашему пользователю настроить DecimalFormat по выбранному шаблону на основе количества пробелов.

6. Заключение​

В этой статье мы кратко рассмотрели различные способы форматирования чисел в Java. Как мы видим, лучшего способа сделать это не существует. Можно использовать множество подходов, поскольку каждый из них имеет свои особенности.

Как всегда, код этих примеров доступен на GitHub .

Источник

Форматирование вывода с помощью printf() в Java

Этот метод является частью класса java.io.PrintStream и обеспечивает форматирование строк, аналогичное функции printf() в C.

2. Синтаксис

Мы можем использовать один из этих методов PrintStream для форматирования вывода:

 System.out.printf(format, arguments);   System.out.printf(locale, format, arguments); 

Мы указываем правила форматирования с помощью параметра формата . Правила начинаются с символа % .

Давайте рассмотрим краткий пример, прежде чем углубляться в детали различных правил форматирования:

 System.out.printf("Hello %s!%n", "World"); 

Это дает следующий результат:

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

2.1. Правила формата​

Давайте посмотрим на строку формата более внимательно. Он состоит из литералов и спецификаторов формата. Спецификаторы формата включают флаги, ширину, точность и символы преобразования в этой последовательности:

%[flags][width][.precision]conversion-character 

Спецификаторы в скобках являются необязательными.

Внутри printf() использует класс java.util.Formatter для разбора строки формата и создания вывода. Дополнительные параметры строки формата можно найти в Javadoc Formatter .

2.2. Преобразование символов

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

Символы преобразования допустимы только для определенных типов данных. Вот некоторые из них:

  • s форматирует строки.
  • d форматирует десятичные целые числа.
  • f форматирует числа с плавающей запятой.
  • t форматирует значения даты/времени.

Мы рассмотрим их и некоторые другие позже в этом руководстве.

2.3. Дополнительные модификаторы

[ Флаги `] ` определяют стандартные способы изменения вывода и чаще всего используются для форматирования целых чисел и чисел с плавающей запятой.

[width] указывает ширину поля для вывода аргумента. Он представляет собой минимальное количество символов, записываемых на выходе.

[.precision] указывает количество разрядов точности при выводе значений с плавающей запятой. Кроме того, мы можем использовать его для определения длины подстроки для извлечения из String .

3. Разделитель строк

Чтобы разбить строку на отдельные строки, у нас есть спецификатор % n :

 System.out.printf("foreach%nline%nterminator"); 

Приведенный выше фрагмент кода выдаст следующий результат:

Источник

Читайте также:  Полосы прокрутки
Оцените статью