Массив формата Java (используя класс Formatter) - PullRequest
3 голосов
/ 15 октября 2011

У нас есть метод, который выглядит следующим образом:

public String getCommandString(Object...args) {
    return this.code + " " + String.format(this.pattern, args);
}

Где this.code:int и this.pattern:String.

Этот метод обычно называется так:

// cmd.code = 20
// cmd.pattern = "%1$s = %2$d"
String str = cmd.getCommandString("foo", 3);   // -> "20 foo = 3"

и другие строковые шаблоны (это для очень простой текстовой программы сервер-клиент)

Теперь можно ли в шаблоне учитывать переменное количество аргументов, например

// cmd.code = 20
// cmd.pattern = ???
String s1 = cmd.getCommandString("a", "b", "c");               // -> 20 a b c
String s2 = cmd.getCommandString("Hello", "world");            // -> 20 Hello world
String s3 = cmd.getCommandString("1", "2, "3", "4", "5", "6"); // -> 20 1 2 3 4 5 6

Предположим, возможно, что каждый аргумент имеет одинаковый тип (строки)? Или мне нужно переопределить метод и отформатировать строку вручную? Более конкретно, я ищу общий строковый шаблон для форматирования переменного числа аргументов (одного типа). Я помню, как делал такое в C, но возможно ли это в Java?

Ответы [ 2 ]

3 голосов
/ 15 октября 2011

Функциональность, которую вы запрашиваете, если я правильно понимаю, не существует. Вот раздел javadoc из класса Formatter:

Спецификаторы формата могут ссылаться на аргументы тремя способами:

Явная индексация используется, когда спецификатор формата содержит индекс аргумента. Индекс аргумента - это десятичное целое число, указывающее позицию аргумента в списке аргументов. На первый аргумент ссылается «1 $», на второй - «2 $» и т. Д. На аргумент можно ссылаться более одного раза. Например:

formatter.format ("% 4 $ s% 3 $ s% 2 $ s% 1 $ s% 4 $ s% 3 $ s% 2 $ s% 1 $ s", "a", "b", "c", "d") // -> "d c b a d c b a"

Относительная индексация используется, когда спецификатор формата содержит флаг '<' ('\ u003c'), который вызывает повторное использование аргумента для предыдущего спецификатора формата. Если предыдущий аргумент отсутствует, создается исключение MissingFormatArgumentException. </p>

formatter.format ("% s% s%" a b b b " // "c" и "d" игнорируются, потому что на них нет ссылок

Обычная индексация используется, когда спецификатор формата не содержит ни индекса аргумента, ни флага «<». Каждому спецификатору формата, который использует обычное индексирование, присваивается последовательный неявный индекс в список аргументов, который не зависит от индексов, используемых явным или относительным индексированием. </p>

formatter.format ("% s% s% s% s", "a", "b", "c", "d") // -> "a b c d"

Возможно иметь строку формата, которая использует все формы индексации, например:

formatter.format ("% 2 $ s% s%" b a a b " // "c" и "d" игнорируются, потому что на них нет ссылок

Максимальное количество аргументов ограничено максимальным измерением массива Java, как определено в Спецификации виртуальной машины Java. Если индекс аргумента не соответствует доступному аргументу, генерируется исключение MissingFormatArgumentException.

Если аргументов больше, чем спецификаторов формата, дополнительные аргументы игнорируются.

То, что вы просите, - это способ построения шаблона, который будет принимать произвольное количество аргументов и использовать их все. Проблема заключается в том, что класс Formatter может связывать спецификаторы формата только с аргументами явно, относительно или обычно. В каждом из этих случаев количество спецификаторов формата является фиксированным . Нет такой конструкции, в которой вы можете повторить или зациклить спецификатор формата. Относительная техника выглядит многообещающе, но нет способа ее вложить или зациклить.

0 голосов
/ 26 октября 2016

Используйте это

public String getCommandString(Object...args) {
    // Want to have a "-" if args are not given
    return this.code + " " + args != null && args.length > 0
            ? Arrays.stream(args).map(o -> o.toString()).collect(Collectors.joining(" + ")) : "-";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...