Formatter 不能用在字符串上吗?
May Formatter not be used on Strings?
当我检查以下代码的结果时,我被难住了:
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 参考指出
Strings may be formatted using the static method String.format
.
但没有迹象表明 new Format().formatter(...)
可能 不会 用于字符串。 (如果我使用构造函数 Format(Appendable matrix)
一切都按预期工作。)
这种不稳定行为的解释是什么?
两种情况其实都是expected behaviour。 Formatter
class 有一个内部缓冲区(默认为 StringBuilder
),它将每次调用 format
的结果附加到其中,toString()
方法 returns缓冲区的全部内容。所以你第一次打电话
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
只是输出格式化行。
当我检查以下代码的结果时,我被难住了:
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 参考指出
Strings may be formatted using the static method
String.format
.
但没有迹象表明 new Format().formatter(...)
可能 不会 用于字符串。 (如果我使用构造函数 Format(Appendable matrix)
一切都按预期工作。)
这种不稳定行为的解释是什么?
两种情况其实都是expected behaviour。 Formatter
class 有一个内部缓冲区(默认为 StringBuilder
),它将每次调用 format
的结果附加到其中,toString()
方法 returns缓冲区的全部内容。所以你第一次打电话
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
只是输出格式化行。