Пользователь Виталий Рыжаков
Виталий Рыжаков
40 уровень
Москва

Класс MessageFormat

Статья из группы Random
В этой статье я хочу рассказать о классе MessageFormat, который используется в задаче 2412 (task2412). Класс MessageFormat - 1Класс MessageFormat предназначен для создания строк. Данный класс Java принимает набор объектов, форматирует их, а затем вставляет форматированные строки в шаблон в соответствующих местах. Это своего рода альтернатива (или даже дополнение) к статическому методу String.format. Для начала простой пример использования данного Java класса без создания объекта, а используя статический метод:

        int planet = 7;
        String event = "a disturbance in the Force";
        String result = MessageFormat.format(
                "At {0, time, medium} on {0, date}, there was {1} on planet {2, number, integer}.",
                new Date(), event, planet);
        System.out.println(result);
Здесь вызывается статический метод MessageFormat.format, в который передаются аргументами шаблон строки и, собственно, объекты, которые будут вставлены в места, ограниченные скобками {}. В скобках задается позиция объекта начиная с 0, а также тип форматирования, если таковой имеется. Вывод будет такой:

At 21:25:54 on 28 апр. 2018 г., there was a disturbance in the Force on planet 7.
В следующем примере уже создается объект класса MessageFormat:

        int fileCount = 1273;
        String diskName = "MyDisk";
        Object[] testArgs = {fileCount, diskName};

        MessageFormat form = new MessageFormat(
                "The disk \"{1}\" contains {0} file(s).");

        System.out.println(form.format(testArgs));
При создании объекта класса MessageFormat в его конструктор передается шаблон строки. Далее, при вызове метода format у объекта, туда в качестве аргумента передается массив объектов, которые будут вставлены в шаблон строки. Вывод будет такой:

The disk "MyDisk" contains 1 273 file(s).
Также возможно сделать так, что в зависимости от значения переменной будет выбираться необходимый текст. Своего рода реализация оператора if...else, только с помощью класса ChoiceFormat. Вот код:

        MessageFormat form = new MessageFormat("Я могу {1} {0}.");
        int count = 2;
        String exercise = "подтянуться";
        Object[] testArgs = {count, exercise};

        double[] filelimits = {0,2,5};
        String[] filepart = {"{0} раз","{0} раза","{0} раз"};
        ChoiceFormat fileform = new ChoiceFormat(filelimits, filepart);
        form.setFormatByArgumentIndex(0, fileform);
        
        System.out.println(form.format(testArgs));
Данный код в зависимости от значения переменной count меняет вывод строки следующим образом:
  • если count = 1 вывод будет такой

    
    Я могу подтянуться 1 раз.
    
  • если count = 2 вывод будет такой

    
    Я могу подтянуться 2 раза.
    
  • если count = 7 вывод будет такой

    
    Я могу подтянуться 7 раз.
    
В данном коде создается массив double[] filelimits, в котором указываются пределы значений, при которых будет меняться вывод строк. А в массиве String[] filepart указываются те самые варианты строк, которые могут быть использованы. Условия выбора варианта строки от значения переменной определяются следующим образом: выберется вариант filepart[j], если filelimits[j] =< count < filelimits[j+1]. Далее создается объект ChoiceFormat fileform и в его конструктор передаются массивы double[] filelimits и String[] filepart. С помощью метода form.setFormatByArgumentIndex(0, fileform) мы говорим объекту MessageFormat form, что когда вызовут метод format, то для индекса 0 в шаблоне строки используй форматирование, которое было задано в объекте ChoiceFormat fileform. Хорошо. У вас уже в принципе могла появиться мысль никогда не использовать Java класс MessageFormat, но знайте, что это еще не все примочки. Имеется вот такой код:

        MessageFormat pattform = new MessageFormat("There {0} on {1}.\n{2} {2}");
        int count = 0;
        Date date = new Date();
        Object[] testArgs = {count, "ADisk", date, date};

        double[] filelimits = {0,1,2};
        String[] filepart = {"are no files","is one file","are {0} files"};
        ChoiceFormat fileform = new ChoiceFormat(filelimits, filepart);

        Format[] testFormats
                = {fileform, null, DateFormat.getDateInstance(DateFormat.SHORT), DateFormat.getTimeInstance(DateFormat.SHORT)};
        pattform.setFormats(testFormats);
        
        System.out.println(pattform.format(testArgs));
Здесь основная фишка в массиве Format[] testFormats. В данный массив мы заносим объекты (реализующие абстрактный класс Format), которые отвечают за форматирование объектов, определенных в массиве Object[] testArgs. Если объект не нуждается в форматировании, то в массиве Format[] testFormats записывается null. Далее с помощью метода pattform.setFormats(testFormats) мы говорим объекту MessageFormat pattform, что для всех индексов в шаблоне строки надо использовать форматирование, определенное в массиве Format[] testFormats. Для данного примера вывод будет такой:

There are no files on ADisk.
28.04.18 22:10
На этом все и я надеюсь, что при решении задачи 2412 у вас не возникнет сложностей.
Комментарии (37)
Чтобы просмотреть все комментарии или оставить свой,
перейдите в полную версию
Andrii 26 уровень
17 апреля 2021
Отвратный класс как и задача
Herr Ives 30 уровень
27 февраля 2021
спасибо!
Agent Smith 37 уровень
28 ноября 2020
Хороший, удобный класс. Можно конечно получить тот же результат с помощью if-else, но тогда будет намного больше кода.
Kroak 29 уровень, Москва
15 октября 2020
Не спешите с выводами. Да, на первый взгляд - всё плохо и сложно. Но если немного разобраться, то данный способ становится очень удобным из-за своей гибкости.
Alexander Boyko 26 уровень, Чебоксары
5 октября 2020
2 дня пытаюсь решить эту задачу....😡. У меня появилась , не только мысль не использовать этого класс MessageFormat . Но и взглянуть автору этого класса в глаза !!😡🤬
Damir 26 уровень
17 сентября 2020
"У вас уже в принципе могла появиться мысль никогда не использовать Java класс MessageFormat." Абсолютно верная догадка.
barrrssss 35 уровень, Харьков
15 августа 2020
В статье есть неточность: В данный массив мы заносим объекты (реализующие абстрактный класс Format), которые отвечают за форматирование объектов, определенных в массиве Object[] testArgs. Если объект не нуждается в форматировании, то в массиве Format[] testFormats записывается null. Из этого складывается впечатление, что форматы будут применяться к объектам в массиве в соответствии с индексами массивов, но на самом деле форматы применяются к переменным шаблона строки в порядке с лева на право.
Applejack 41 уровень, Минск
14 мая 2020
Вы бы хоть код меняли, когда статьи копипастите
Даурен Джумагалиев 29 уровень, Атырау
13 апреля 2020
Object[] testArgs = {count, "ADisk", date, date}; Почему здесь date 2 раза? не нашел где второй data используется
Tatiana 32 уровень, Москва
12 апреля 2020