Может ли Formatter не использоваться в строках? - PullRequest
0 голосов
/ 10 июня 2018

Я был озадачен, когда проверил результат следующего кода:

public class StringBuilderTester {

    public static void main(String[] args) {
        StringBuilder matrix = new StringBuilder();
        Random r = new Random();
        Formatter formatter = new Formatter();
        for (int j=0;j<10;j++) {
            String[] strings = new String[10];
            StringBuilder formatString = new StringBuilder();
            for (int i=0;i<10;i++) {
                formatString.append("%-10.5s");
                strings[i] = new Integer(r.nextInt(10)).toString();
            }
            formatString.append("\n");
            matrix.append(formatter.format(formatString.toString(), strings));  //gives me unexpected result: 1+2+3+..+10=55 lines of 10 cols of random ints
            //matrix.append(String.format(formatString.toString(), strings));  //gives me expected results: 10 lines of 10 cols of random ints
        }
        System.out.println(matrix.toString());
    }
}

Я получаю 55 (!) Строк по 10 столбцов, каждый из которых представляет собой аккуратно отформатированные целые числа: строка 1, затем строка 1 и строка 2,затем строки 1, 2 и 3 и так далее.Кажется, что formatter.format работает постепенно.

При изменении formatter.format на String.format результат будет таким, как ожидалось: 10 строк аккуратно отформатированных целых чисел.

Ссылка на Java гласит, что

Строки могут быть отформатированы с использованием статического метода String.format.

Но нет никаких признаков того, что new Format().formatter(...) не может использоваться для строк.(И если я использую конструктор Format(Appendable matrix), все будет работать как положено.)

Чем объясняется такое ошибочное поведение?

1 Ответ

0 голосов
/ 10 июня 2018

Оба случая на самом деле ожидаемое поведение .Класс Formatter имеет внутренний буфер (по умолчанию a StringBuilder), к которому он добавляет результат каждого вызова к format, а метод toString() возвращает все содержимое буфера.Поэтому при первом вызове

matrix.append(formatter.format(formatString.toString(), strings));

он добавляет row1 в буфер форматирования, а затем добавляет его в матрицу.Вызовите его еще раз, и он добавляет строку 2 в буфер, но теперь буфер содержит строки 1 и 2, поэтому обе строки добавляются в матрицу, которая теперь имеет строку 1, строку 1, строку 2. Это продолжается и заканчивается добавлением 55.Всего строк.

old matrix    +    buffer    =    new matrix
                   1              1
1                  12             112
112                123            112123
112123             1234           1121231234
...and so on

С другой стороны, если вы просто вызовете String.format, он выдаст тот же вывод, что и formatter.format, но не добавит его ни в один буфер.Таким образом, на каждой итерации цикла к матрице добавляется только последняя созданная строка, что является ожидаемым результатом.

TL; DR: formatter.format добавляет отформатированную строку во внутренний буфер, а затем выводит весь буфер,в то время как String.format просто выводит отформатированную строку.

...