可以在字符串上使用Formatter吗?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (60)

当我检查以下代码的结果时,如下:

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.formatString.format结果时,如预期:10行整齐格式的整数。

Java参考说明了这一点

可以使用静态方法格式化字符串String.format

但没有迹象表明new Format().formatter(...)可能不会用于字符串。(如果我使用构造函数,Format(Appendable matrix)一切都按预期工作。)

对这种不稳定行为的解释是什么?

提问于
用户回答回答于

两种情况都是预期的行为。所述Formatter类具有内部缓冲器(默认一个StringBuilder),其它附加每次调用的结果format,并且toString()方法返回缓冲器的全部内容。所以你第一次调用:

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

它将row1添加到格式化程序缓冲区,然后将其附加到矩阵。再次调用它并将第2行添加到缓冲区,但现在缓冲区包含row1和row2,因此两行都会添加到矩阵中,现在它有第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只输出格式化的行。

扫码关注云+社区

领取腾讯云代金券