Статьи

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

Я могу вспомнить множество случаев, когда я видел, как другие пишут ненужный Java-код, и я писал ненужный Java-код из-за недостаточной осведомленности о классе JDK, который уже обеспечивает желаемую функциональность. Одним из примеров этого является запись связанных со временем констант с использованием жестко закодированных значений, таких как 60 , 24 , 1440 и 86400, когда TimeUnit обеспечивает лучший стандартизированный подход. В этом посте я рассмотрю еще один пример класса, который предоставляет функциональность, которую я часто видел разработчиками, — NumberFormat .

Класс NumberFormat является частью пакета java.text , который также включает часто используемые классы DateFormat и SimpleDateFormat . NumberFormat является абстрактным классом (без открытого конструктора), и экземпляры его потомков получают с помощью перегруженных статических методов с именами, такими как getInstance () , getCurrencyInstance () и getPercentInstance () .

валюта

Следующий листинг кода демонстрирует вызов NumberFormat.getCurrencyInstance (Locale) для получения экземпляра, NumberFormatкоторый представляет числа в удобном для валюты формате.

Демонстрация поддержки валюты NumberFormat

    /** 
     * Demonstrate use of a Currency Instance of NumberFormat. 
     */  
    public void demonstrateCurrency()  
    {  
       writeHeaderToStandardOutput("Currency NumberFormat Examples");  
       final NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(Locale.US);  
       out.println("15.5      -> " + currencyFormat.format(15.5));  
       out.println("15.54     -> " + currencyFormat.format(15.54));  
       out.println("15.345    -> " + currencyFormat.format(15.345));  // rounds to two decimal places  
       printCurrencyDetails(currencyFormat.getCurrency());  
    }  
      
    /** 
     * Print out details of provided instance of Currency. 
     * 
     * @param currency Instance of Currency from which details 
     *    will be written to standard output. 
     */  
    public void printCurrencyDetails(final Currency currency)  
    {  
       out.println("Concurrency: " + currency);  
       out.println("\tISO 4217 Currency Code:           " + currency.getCurrencyCode());  
       out.println("\tISO 4217 Numeric Code:            " + currency.getNumericCode());  
       out.println("\tCurrency Display Name:            " + currency.getDisplayName(Locale.US));  
       out.println("\tCurrency Symbol:                  " + currency.getSymbol(Locale.US));  
       out.println("\tCurrency Default Fraction Digits: " + currency.getDefaultFractionDigits());  
    }


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

==================================================================================
= Currency NumberFormat Examples
==================================================================================
15.5      -> $15.50
15.54     -> $15.54
15.345    -> $15.35
Concurrency: USD
 ISO 4217 Currency Code:           USD
 ISO 4217 Numeric Code:            840
 Currency Display Name:            US Dollar
 Currency Symbol:                  $
 Currency Default Fraction Digits: 2

Приведенный выше код и связанный с ним вывод демонстрируют, что NumberFormatэкземпляр, используемый для валюты (на самом деле a DecimalFormat), автоматически применяет соответствующее количество цифр и соответствующий символ валюты на основе локали.

Процентное соотношение

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

Демонстрация формата процента NumberFormat

    /** 
     * Demonstrate use of a Percent Instance of NumberFormat. 
     */  
    public void demonstratePercentage()  
    {  
       writeHeaderToStandardOutput("Percentage NumberFormat Examples");  
       final NumberFormat percentageFormat = NumberFormat.getPercentInstance(Locale.US);  
       out.println("Instance of: " + percentageFormat.getClass().getCanonicalName());  
       out.println("1        -> " + percentageFormat.format(1));  
       // will be 0 because truncated to Integer by Integer division  
       out.println("75/100   -> " + percentageFormat.format(75/100));  
       out.println(".75      -> " + percentageFormat.format(.75));  
       out.println("75.0/100 -> " + percentageFormat.format(75.0/100));  
       // will be 0 because truncated to Integer by Integer division  
       out.println("83/93    -> " + percentageFormat.format((83/93)));  
       out.println("93/83    -> " + percentageFormat.format(93/83));  
       out.println(".5       -> " + percentageFormat.format(.5));  
       out.println(".912     -> " + percentageFormat.format(.912));  
       out.println("---- Setting Minimum Fraction Digits to 1:");  
       percentageFormat.setMinimumFractionDigits(1);  
       out.println("1        -> " + percentageFormat.format(1));  
       out.println(".75      -> " + percentageFormat.format(.75));  
       out.println("75.0/100 -> " + percentageFormat.format(75.0/100));  
       out.println(".912     -> " + percentageFormat.format(.912));  
    }  


==================================================================================
= Percentage NumberFormat Examples
==================================================================================
1        -> 100%
75/100   -> 0%
.75      -> 75%
75.0/100 -> 75%
83/93    -> 0%
93/83    -> 100%
.5       -> 50%
.912     -> 91%
---- Setting Minimum Fraction Digits to 1:
1        -> 100.0%
.75      -> 75.0%
75.0/100 -> 75.0%
.912     -> 91.2%

Код и выходные данные процентного NumberFormatиспользования демонстрируют, что по умолчанию экземпляр NumberFormat(на самом деле a DecimalFormatв данном случае), возвращаемый методом NumberFormat.getPercentInstance (Locale), не имеет дробных цифр, умножает предоставленное число на 100 (предполагается, что это десятичный эквивалент процента, когда предоставляется), и добавляет знак процента (%).

Целые

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

Демонстрация целочисленного формата NumberFormat

    /** 
     * Demonstrate use of an Integer Instance of NumberFormat. 
     */  
    public void demonstrateInteger()  
    {  
       writeHeaderToStandardOutput("Integer NumberFormat Examples");  
       final NumberFormat integerFormat = NumberFormat.getIntegerInstance(Locale.US);  
       out.println("7.65   -> " + integerFormat.format(7.65));  
       out.println("7.5    -> " + integerFormat.format(7.5));  
       out.println("7.49   -> " + integerFormat.format(7.49));  
       out.println("-23.23 -> " + integerFormat.format(-23.23));  
    }


==================================================================================
= Integer NumberFormat Examples
==================================================================================
7.65   -> 8
7.5    -> 8
7.49   -> 7
-23.23 -> -23

Как показано в приведенном выше коде и связанных выходных данных, NumberFormatметод getIntegerInstance (Locale) возвращает экземпляр, который представляет предоставленные цифры в виде целых чисел.

Фиксированные цифры

Следующий листинг кода и связанный с ним вывод демонстрируют использование NumberFormatдля печати представления чисел с плавающей запятой с фиксированной запятой. Другими словами, это использование NumberFormatпозволяет представлять число с точно заданным количеством цифр слева от десятичной точки («целые» цифры) и справа от десятичной точки («дробные» цифры).

Демонстрация числового формата для чисел с фиксированной точкой

    /** 
     * Demonstrate generic NumberFormat instance with rounding mode, 
     * maximum fraction digits, and minimum integer digits specified. 
     */  
    public void demonstrateNumberFormat()  
    {  
       writeHeaderToStandardOutput("NumberFormat Fixed-Point Examples");  
       final NumberFormat numberFormat = NumberFormat.getNumberInstance();  
       numberFormat.setRoundingMode(RoundingMode.HALF_UP);  
       numberFormat.setMaximumFractionDigits(2);  
       numberFormat.setMinimumIntegerDigits(1);  
       out.println(numberFormat.format(234.234567));  
       out.println(numberFormat.format(1));  
       out.println(numberFormat.format(.234567));  
       out.println(numberFormat.format(.349));  
       out.println(numberFormat.format(.3499));  
       out.println(numberFormat.format(0.9999));  
    } 


==================================================================================
= NumberFormat Fixed-Point Examples
==================================================================================
234.23
1
0.23
0.34
0.35
1

Вышеприведенный код и связанный с ним вывод демонстрируют точный контроль минимального количества «целых» цифр, которые должны быть представлены слева от десятичного разряда (по крайней мере, один, поэтому в случае необходимости отображается ноль), и максимального количества «дроби» цифры справа от десятичной точки. Хотя это и не показано, максимальное количество целых цифр и минимальное количество цифр дроби также могут быть указаны.

Вывод

Я использовал этот пост, чтобы посмотреть, как NumberFormat можно использовать для представления чисел по-разному (валюта, процент, целое число, фиксированное количество десятичных знаков и т. Д.), И часто означает, что для втискивания чисел в эти цифры не требуется писать или сокращать код. форматы. Когда я впервые начал писать этот пост, я предполагал включить в него примеры и обсуждение прямых потомков NumberFormat( DecimalFormat и ChoiceFormat ), но решил, что этот пост уже достаточно длинный. Я могу написать об этих потомках NumberFormatв будущих сообщениях в блоге.