Форматирование чисел в Android-приложении: уроки программирования

Форматирование чисел в Android-приложении: уроки программирования

Проблема

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

Решение

Используйте функцию String.format() или один из подклассов класса NumberFormat.

Обсуждение

Функция printf() была впервые включена в язык программирования С в 1970- х гг. и использовалась на многих других языках, включая Java. Вот простой пример printf() в версии Java SE:

System.out.printf("Hello %s at %s%n", userName, time);

В предыдущем примере можно было бы напечатать что-то вроде этого:

Hello Robin at Wed Jun 16 08:38:46 EDT 2019

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

String msg = String.format("Hello %s at %s%n", userName, time);

Если раньше вы не видели функцию printf(), то первым аргументом, очевидно, является строка кода формата, а любые другие аргументы (имя пользователя и время) являются значениями, которые нужно форматировать. Коды формата начинаются со знака процента (%) и имеют хотя бы один код для элементарных типов.

В табл. 1 приведены некоторые коды для элементарных типов.

Таблица 1. Некоторые коды для форматирования элементарных типов

Символ

Значение

S

Строка (конвертировать элементарные значения с использованием значений по умолчанию, конвертировать объекты с помощью функции toString)

d

Десятичное целое число (int, long)

f

Число с плавающей точкой (float, double)

n

Новая строка

t

Форматы времени/даты, специфичные для Java; См. в конце статьи

 

Форматирование даты по умолчанию довольно уродливое, поэтому нам часто нужно расширять его. Возможности форматирования printf() на самом деле размещены в классе java.util.Formatter, на который должна быть сделана ссылка.

В отличие от функции printf() на других языках, которые вы, возможно, использовали, все эти форматные процедуры необязательно позволяют ссылаться на аргументы по их числу, помещая число плюс знак доллара после ввода знака %, но до собственно кода форматирования. Например, %2$3.1f означает форматирование второго аргумента как десятичного числа с тремя символами и одной цифрой после десятичной точки. Эта нумерация может использоваться для двух целей: изменить порядок, в котором выводятся аргументы (часто полезны с интернационализацией), и ссылаться на данный аргумент более одного раза. Формат даты/времени t требует после него второго символа, такого как Y для года, m для месяца и т. д. Здесь мы берем аргумент time и извлекаем из него несколько полей:

msg = String.format("Hello at %1$tB %1$td, %1$tY%n", time);

Это выдаст: July 4, 2010.

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

msg = String.format("Latitude: %10.6f", latitude);

Результат может выглядеть так:

Latitude: -79.281818

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

Общие форматы

В языке Java есть целый пакет java.text, который полон процедур форматирования как общих и гибких, так и всех, что вы можете себе представить. Как и в функции printf(), в нем используется язык форматирования, описанный на онлайн-странице документации. Рассмотрим представление чисел. В Северной Америке число “одна тысяча двадцать четыре и четверть” имеет вид 1, 024.25; в большинстве стран Европы — 1 024,25, а в некоторых других странах это может быть написано как 1.024, 25. Форматирование валют и процентов также отличается большим разнообразием. Попытка отслеживать это сама по себе быстро переутомила бы среднего разработчика программного обеспечения.

К счастью, пакет java.text включает класс Locale. Кроме того, среда выполнения Java или Android автоматически устанавливает объект класса Locale по умолчанию на основе среды пользователя; этот код работает как на настольных компьютерах в среде Java, так и на устройствах Android. Чтобы обеспечить форматирование, настроенное для чисел, валют и процентов, класс NumberFormat имеет статические встроенные методы, которые обычно возвращают объект класса Decimal Format с уже созданным шаблоном. Объект класса Decimal Format, соответствующий локализации пользователя, может быть получен с помощью встроенного метода NumberFormat.getlnstance() и управляться с использованием set-методов. Удивительно, но метод setMinimumlntegerDigits() оказывается простым способом создания формата чисел с ведущими нулями. Рассмотрим пример.

Пример 2. Пример форматирования числа

import java.text.NumberFormat;

/*
 * Форматирование числа по умолчанию и по желанию пользователя.
 */
public class NumFormat2 {
    /** Множество форматов  */
    public static final double data[] = {
        0, 1, 22d/7, 100.2345678
    };

    public static void main(String[] av) {
        // Получаем экземпляр формата
        NumberFormat form = NumberFormat.getInstance();

        // Приводим его к виду 999.99[99]
        form.setMinimumIntegerDigits(3);
        form.setMinimumFractionDigits(2);
        form.setMaximumFractionDigits(4);

        // Выводим число в соответствующем формате
        for (int i=0; i<data.length; i++)
            System.out.println(data[i] + "\tformats as " +
                form.format(data[i]));
    }
}

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

Например, инструкция $ java NumFormat2 0.0 форматирует нуль как 000.00; с аргументом 1.0 она создает представление 001.00, число 3.142857142857143 она представляет как 003.1429, а 100.2345678 — как 100.2346.

Вы также можете создать объект класса DecimalFormat с определенным шаблоном или динамически изменять шаблон с помощью метода applyPattern(). В табл. 2 показаны некоторые из наиболее распространенных шаблонных символов.

Таблица 2. Общие СИМВОЛЫ шаблона DecimalFormat

Символ Значение
# Цифра (подавление ведущих нулей)
0 Цифра (указаны ведущие нули)
. Локализованный десятичный разделитель (десятичная точка)
, Локализованный разделитель групп (запятая на английском языке)
- Локализованный минус (знак "минус")
% Показывает значение в процентах
; Отделяет два формата: первый для положительного значения и второй для отрицательного
' Выводит предыдущий символ как таковой
Другие Появляется без обработки

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

Пример 3. Программа демоверсии NumberFormat Java SE

import java.text.DecimalFormat;
import java.text.NumberFormat;

public class NumFormatDemo {
    /** Множество форматов */
    public static final double intlNumber = 1024.25;
    /** Другое множество форматов  */
    public static final double ourNumber = 100.2345678;

    public static void main(String[] av) {

        NumberFormat defForm = NumberFormat.getInstance();
        NumberFormat ourForm = new DecimalFormat("##0.##");
        // toPattern() will reveal the combination of #0., etc.
        // that this particular Locale uses to format with
        System.out.println("defForm's pattern is " +
            ((DecimalFormat)defForm).toPattern());
        System.out.println(intlNumber + " formats as " +
            defForm.format(intlNumber));
        System.out.println(ourNumber + " formats as " +
            ourForm.format(ourNumber));
        System.out.println(ourNumber + " formats as " +
            defForm.format(ourNumber) + " using the default format");
    }
}

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

$ java NumFormatTest
defForm's pattern is #,##0.###
1024.25 formats as 1,024.25
100.2345678 formats as 100.23
100.2345678 formats as 100.235 using the default format

 

Вас заинтересует / Intresting for you:

Распространенные заблуждения о...
Распространенные заблуждения о... 753 просмотров Ирина Светлова Thu, 21 Jun 2018, 18:35:12
Выбор среды для разработки код...
Выбор среды для разработки код... 800 просмотров Rasen Fasenger Sun, 10 Jun 2018, 14:21:35
Как выполнить / скомпилировать...
Как выполнить / скомпилировать... 998 просмотров Rasen Fasenger Thu, 21 Jun 2018, 18:32:00
Аплеты Java и Интернет
Аплеты Java и Интернет 755 просмотров Ирина Светлова Sat, 09 Jun 2018, 10:17:34