Статьи

Пользовательские компактные номера с форматированием JDK 12

Пост « Компактное форматирование чисел доходит до JDK 12 » был предметом обсуждения в ветке java subreddit . Обеспокоенность, выраженная в этой теме, связана с представлением форматирования компактного числа, касающегося отображаемых цифр точности и отображаемых шаблонов компактного числа. Цифры точности могут быть адресованы с помощью CompactNumberFormat.setMinimumFractionDigits(int) и этот подход более подробно обсуждается в статье « Использование минимальных дробных цифр с JDK 12 Compact Number Formatting ». Вторая проблема (неприязнь к компактным шаблонам, используемым в предварительно CompactNumberFormat экземплярах CompactNumberFormat для определенных языков) рассматривается в этом посте.

Насколько я могу определить (и я, возможно, что-то упустил), в CompactNumberFormat нет метода, позволяющего задавать шаблоны компактных чисел в существующем экземпляре CompactNumberFormat . Однако, если конструктор для CompactNumberFormat используется для получения экземпляра этого класса (вместо использования одного из перегруженных статических фабричных методов в NumberFormat ), то шаблоны компактных чисел могут быть переданы через этот конструктор в новый экземпляр CompactNumberFormat . Это продемонстрировано в следующем листинге кода (также доступен на GitHub ).

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
 * Provides an instance of {@code CompactNumberFormat} that has been
 * custom created via that class's constructor and represents an
 * alternate Germany German representation to that provided by an
 * instance of {@code CompactNumberFormat} obtained via the static
 * factory methods of {@code NumberFormat} for {@code Locale.GERMANY}.
 *
 * @return Instance of {@code CompactNumberFormat} with customized
 *    alternate German compact pattern representations.
 */
private static CompactNumberFormat generateCustomizedGermanCompactNumberFormat()
{
   final String[] germanyGermanCompactPatterns
      = {"", "", "", "0k", "00k", "000k", "0m", "00m", "000m", "0b", "00b", "000b", "0t", "00t", "000t"};
   final DecimalFormat germanyGermanDecimalFormat
      = acquireDecimalFormat(Locale.GERMANY);
   final CompactNumberFormat customGermanCompactNumberFormat
      = new CompactNumberFormat(
         germanyGermanDecimalFormat.toPattern(),
         germanyGermanDecimalFormat.getDecimalFormatSymbols(),
         germanyGermanCompactPatterns);
   return customGermanCompactNumberFormat;
}

В приведенном выше листинге кода стоит выделить три элемента:

  1. Конструктор CompactNumberFormat(String, DecimalFormatSymbols, String[]) позволяет передавать в массив массив String для указания шаблонов компактных чисел.
  2. Характер String[] определяющий шаблоны компактных чисел, определен в классе Javadoc для CompactNumberFormat , который гласит: «Шаблоны компактных чисел представлены в виде серии шаблонов, где каждый шаблон используется для форматирования диапазона чисел».

    • Тот же самый Javadoc предоставляет пример на основе локали США, который предоставляет эти значения для диапазона от 10 0 до 10 14, и именно этот пример я адаптировал здесь.
    • Может быть предоставлено больше или меньше 15 шаблонов, но первый предоставленный шаблон всегда соответствует 10 0 . В Javadoc говорится: «Может быть любое количество шаблонов, и они строго основаны на индексе, начиная с диапазона 10 0 ».
    • Для демонстрации здесь я адаптировал шаблоны из наблюдения в потоке subreddit, на который ссылались ранее . Я не знаю много о немецком, но аргумент в пользу суффиксов на основе SI имел большой смысл, и в любом случае это только для иллюстративных целей.
  3. В этом примере я получил два других аргумента для конструктора CompactNumberFormat из предоставленного JDK экземпляра DecimalFormat для немецкой локали Германии ( Locale.GERMANY ). Это гарантировало, что десятичный шаблон и символы десятичного формата моего пользовательского немецкого экземпляра CompactNumberFormat будут такими же, как те, которые связаны с экземпляром, предоставленным JDK.

В приведенном выше листинге кода показан вызов метода с именем acquireDecimalFormat(Locale) для получения JDK-экземпляра DecimalFormat для Locale.GERMANY . Для полноты, этот метод показан ниже.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
 * Provides an instance of {@code DecimalFormat} associated with
 * the provided instance of {@code Locale}.
 *
 * @param locale Locale for which an instance of {@code DecimalFormat}
 *    is desired.
 * @return Instance of {@code DecimalFormat} corresponding to the
 *    provided {@code Locale}.
 * @throws ClassCastException Thrown if I'm unable to acquire a
 *    {@code DecimalFormat} instance from the static factory method
 *    on class {@code NumberFormat} (the approach recommended in the
 *    class-level Javadoc for {@code DecimalFormat}).
 */
private static DecimalFormat acquireDecimalFormat(final Locale locale)
{
   final NumberFormat generalGermanyGermanFormat
      = NumberFormat.getInstance(locale);
   if (generalGermanyGermanFormat instanceof DecimalFormat)
   {
      return (DecimalFormat) generalGermanyGermanFormat;
   }
   throw new ClassCastException(
        "Unable to acquire DecimalFormat in recommended manner;"
      + " presented with NumberFormat type of '"
      + generalGermanyGermanFormat.getClass().getSimpleName()
      + "' instead.");
}

Фрагменты кода, показанные выше, демонстрируют, как шаблоны компактных чисел могут быть настроены для данного экземпляра CompactNumberFormat когда шаблоны компактных чисел, связанные в экземплярах этого класса для данной Locale , нежелательны. Было бы хорошо, если бы в классе CompactNumberFormat был метод, позволяющий переопределить некоторые или все шаблоны компактных чисел, связанные с существующим экземпляром, полученным через статический фабричный класс NumberFormat , но JDK 12 вступил в фазу замедления 2 .

Опубликовано на Java Code Geeks с разрешения Дастина Маркса, партнера нашей программы JCG . См. Оригинальную статью здесь: пользовательские компактные числовые шаблоны с компактным форматированием чисел JDK 12

Мнения, высказанные участниками Java Code Geeks, являются их собственными.