Формат вывода с помощью Java Printf

Изучите различные методы форматирования строк в стиле printf в Java. Язык Java адаптировал это форматирование из языка C, но Java добавляет некоторые дополнительные функции безопасности типов и удобства, такие как списки аргументов переменной длины и автоупаковка примитивных типов.

1. Formatter.format() — основа форматирования текста

Основным методом в основе форматирования текста является класс java.util.Formatter и его метод format(). Метод format() использует специальные строки/шаблоны формата, встроенные в текст, чтобы сообщить движку форматирования, где размещать аргументы метода. Для простоты он принимает списки аргументов переменной длины.

Этот метод принимает необязательный экземпляр Locale для форматирования, специфичного для локали.

format(String, arg1, arg2, arg3...)format(Locale, String, arg1, arg2, arg3...)

Вот еще несколько методов, которые используют этот метод внутри себя, например:

  • String.format(): помогает получить отформатированные строки.
  • PrintStream.printf(): помогает записывать форматированный вывод на стандартный вывод консоли, в файл или в сетевое соединение.
String name = "Lokesh";Integer age = 40;String formattedString_1 = new Formatter().format("My name is %s and I am %d years old.\n", name, age).toString();String formattedString_2 = String.format("My name is %s and I am %d years old.\n", name, age);System.out.print(formattedString_1);System.out.print(formattedString_2);System.out.printf("My name is %s and I am %d years old.\n", name, age);

Приведенная выше программа выдает один и тот же результат 3 раза.

 Меня зовут Локеш и мне 40 лет.Меня зовут Локеш и мне 40 лет.Меня зовут Локеш и мне 40 лет.

Также следует отметить, что format() не является потокобезопасным, поэтому необходимо принять необходимые меры предосторожности.

2. Символы преобразования

В предыдущем примере %s и %d — это символы преобразования, которые заменяются движком форматирования во время выполнения. Существует еще много подобных шаблонов, соответствующих примитивам и различным типам, таким как классы даты и времени.

2.1 Преимущества

Эти специализированные символы преобразования выполняют три задачи:

  • Они добавляют уровень безопасности типов. Например, указав %d, мы гарантируем, что в этом месте форматируется только целочисленный тип; в противном случае мы получим исключение IllegalFormatConversionException во время выполнения. Аналогично, другие синтаксические ошибки будут выдавать определенные подтипы исключения IllegalFormatException.
  • Форматирование текста чувствительно к локали и позволяет отображать числа, проценты, даты и время на многих языках, просто указав локаль в качестве аргумента.
  • Дополнительные флаги могут быть использованы для дальнейшей настройки макета. Например, для чисел с плавающей точкой мы можем указать точность в строке формата.

2.2 Синтаксис

Общая структура строки встроенного формата выглядит следующим образом:

%[argument_index$][flags][width][.precision]conversion_type
  • В приведенном выше выражении аргументы в скобках [] являются необязательными.
  • Argument_index можно использовать для переупорядочивания или повторного использования отдельных аргументов из списка аргументов переменной длины, ссылаясь на них по номеру. Первый аргумент обозначается как «1$», второй — как «2$» и т. д.
  • Поле флагов содержит один или несколько специальных символов флагов, управляющих форматом.
  • Поля ширины и точности управляют размером выводимых данных для текста и чисел с плавающей точкой.
  • Символ преобразования является обязательным и определяет формат аргумента.

Наиболее часто используемые типы преобразования:

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

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

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

Если индекс аргумента не соответствует доступному аргументу, то выдается MissingFormatArgumentException. Если аргумент равен null, то результатом будет строка «null».

 System.out.format("Значение равно %s", null); //Выводит 'Значение равно null'

3. Примеры форматирования

Давайте рассмотрим простые примеры, чтобы понять различные способы форматирования текста.

3.1. Вставка нового разделителя строк

Вставьте шаблон преобразования %n, чтобы вставить новый разделитель строк, возвращаемый System.lineSeparator() в форматированный вывод.

System.out.format("Строка 1%nСтрока 2%nСтрока 3");

Эта программа выводит:

 Линия 1Линия 2Строка 3

3.2 Использование индекса аргументов

Используйте Index$ между обязательным символом % и строкой преобразования для ссылки на аргумент. Мы можем ссылаться на аргумент несколько раз в одной строке. Кроме того, мы можем ссылаться на аргументы в любом желаемом нами порядке.

В следующем примере мы ссылаемся на первый аргумент 2 раза в строке.

 System.out.printf("Произведение %1$d и %1$d равно: %2$d", 2, 4); //Печатает 'Произведение 2 и 2 равно: 4'

3.3 Форматирование строк

Помимо использования %s для обычных форматов строк, мы можем использовать %S для форматирования строк в ВЕРХНЕМ РЕГИСТРЕ.

 System.out.printf("Название блога: %s", "howtodoinjava"); //Выводит 'Название блога: howtodoinjava'System.out.printf("Название блога: %S", "howtodoinjava"); //Выводит 'Название блога: HOWTODOINJAVA'

Форматирование строк также может использоваться для строк с заполнением. Используйте положительное число для строки с заполнением справа и отрицательное число для строки с заполнением слева.

 System.out.printf("'%15s' %n", "howtodoinjava"); //Печатает ' howtodoinjava'System.out.printf("'%-15s' %n", "howtodoinjava"); //Выводит 'howtodoinjava'

Чтобы ограничить форматированную строку подстрокой максимальной длины, используйте шаблон XY, где X — это заполнение, а Y — количество символов. В следующем примере мы сначала создаем подстроку длиной 3, а затем дополняем ее до 15 символов слева.

System.out.printf("'%15.3s' %n", "howtodoinjava"); //Выводит 'как'

Чтобы отобразить знак процента в отформатированной строке, используйте %%. Здесь знак процента экранируется с помощью знака процента.

 System.out.printf("Процентная ставка составляет %d%%", 15); //Выводит 'Процентная ставка составляет 15%'

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

Шаблон %d принимает все целочисленные типы, такие как byte, short, int, long и BigInteger.

 System.out.printf("Значение целого числа равно %d %n", 10); //Выводит 'Значение целого числа равно 10'System.out.printf("Длинное значение равно %d %n", 10L); //Печатает 'Длинное значение равно 10'System.out.printf("Значение BigInteger равно %d %n", BigInteger.TEN); //Выводит 'Значение BigInteger равно 10'

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

 System.out.printf("Значение с плавающей точкой равно %f %n", 10.0f); //Печатает 'Значение с плавающей точкой равно 10.000000'

Используйте шаблон %.Pf для добавления точности с плавающей точкой в отформатированную строку.

 System.out.printf("Значение с плавающей точкой равно %.2f %n", 10.0f); //Печатает 'Значение с плавающей точкой равно 10.00'

Для форматирования на основе локали передайте Locale в качестве первого аргумента в методе. Также используйте синтаксис запятых %,d для вставки запятых в числа на основе локали.

 System.out.printf(Locale.US, "Сумма в США составляет %,d %n", 1000000); //Форматирует как '1,000,000'System.out.printf(Locale.ITALY, "Сумма в Великобритании составляет %,d %n", 1000000); //Форматирует как '1.000.000'

3.5 Форматирование даты и времени

Шаблоны преобразования даты и времени начинаются с символов t или T, за которыми следуют более конкретные шаблоны для отображения конкретной информации о дате и времени. Для более контролируемого форматирования для новых классов Java 8(LocalDate, LocalTime и т. д.) предпочтительнее использовать класс DateTimeFormatter.

Для форматирования дат используйте следующие символы:

  • A: полный день недели.
  • d: двузначный день месяца.
  • B: полное название месяца.
  • м: двузначный месяц.
  • Y: год из четырех цифр.
  • y: последние две цифры года.

В следующем примере мы повторно используем индекс аргумента для многократного использования одного и того же экземпляра Date в отформатированной строке. Мы используем tA, tB и tY для форматирования даты.

 Дата сегодня = новая Дата();System.out.printf("%1$tA, %1$tB %1$tY %n", today); //Выводит 'Вторник, Сентябрь 2022'

Аналогично для форматирования частей времени используйте следующие символы:

  • Ч: часы
  • М: минут
  • С: секунды
  • L: время в миллисекундах
  • N: время в наносекундах
  • р: AM или PM
  • z: часовой пояс

Следующий пример печатает время в формате H:N:S. Вторая строка повторно использует параметр для форматирования всех предоставленных шаблонов.

System.out.printf("%1$tH:%1$tM:%1$tS %n", today); //Выводит '22:37:15'

Существует несколько символов преобразования для форматирования распространенных композиций даты/времени.

  • R: Время в 24-часовом формате «%tH:%tM».
  • T: Время в 24-часовом формате «%tH:%tM:%tS».
  • D: Дата в формате «%tm/%td/%ty».
  • F: Полная дата ISO 8601 в формате «%tY-%tm-%td».
  • c: Дата и время в формате «%ta %tb %td %tT %tZ %tY».
 System.out.printf("%tT %n", today); //Выводит '22:37:15'System.out.printf("%tF %n", today); //Выводит '2022-09-13'System.out.printf("%tc %n", today); // Выводит 'Вт 13 сен 22:43:17 IST 2022'

4. Заключение

Этот урок Java научил нас печатать форматированный вывод в Java с помощью методов format() и printf(). Мы научились форматировать простые и сложные шаблоны, включая строки, числа, даты, примитивы и булевы значения.

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

Исходный код на Github

Прокрутить вверх