合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
### [格式化修饰符](https://lingcoder.gitee.io/onjava8/#/book/18-Strings?id=%e6%a0%bc%e5%bc%8f%e5%8c%96%e4%bf%ae%e9%a5%b0%e7%ac%a6) 在插入数据时,如果想要优化空格与对齐,你需要更精细复杂的格式修饰符。以下是其通用语法: ~~~ %[argument_index$][flags][width][.precision]conversion ~~~ 最常见的应用是控制一个字段的最小长度,这可以通过指定*width*来实现。`Formatter` 对象通过在必要时添加空格,来确保一个字段至少达到设定长度。默认情况下,数据是右对齐的,不过可以通过使用`-`标志来改变对齐方向。 与*width*相对的是*precision*,用于指定最大长度。*width*可以应用于各种类型的数据转换,并且其行为方式都一样。*precision*则不然,当应用于不同类型的数据转换时,*precision*的意义也不同。在将*precision*应用于`String`时,它表示打印`string`时输出字符的最大数量。而在将*precision*应用于浮点数时,它表示小数部分要显示出来的位数(默认是 6 位小数),如果小数位数过多则舍入,太少则在尾部补零。由于整数没有小数部分,所以*precision*无法应用于整数,如果你对整数应用*precision*,则会触发异常。 下面的程序应用格式修饰符来打印一个购物收据。这是*Builder*设计模式的一个简单实现,即先创建一个初始对象,然后逐渐添加新东西,最后调用`build()`方法完成构建: ~~~ // strings/ReceiptBuilder.java import java.util.*; public class ReceiptBuilder { private double total = 0; private Formatter f = new Formatter(new StringBuilder()); public ReceiptBuilder() { f.format( "%-15s %5s %10s%n", "Item", "Qty", "Price"); f.format( "%-15s %5s %10s%n", "----", "---", "-----"); } public void add(String name, int qty, double price) { f.format("%-15.15s %5d %10.2f%n", name, qty, price); total += price * qty; } public String build() { f.format("%-15s %5s %10.2f%n", "Tax", "", total * 0.06); f.format("%-15s %5s %10s%n", "", "", "-----"); f.format("%-15s %5s %10.2f%n", "Total", "", total * 1.06); return f.toString(); } public static void main(String[] args) { ReceiptBuilder receiptBuilder = new ReceiptBuilder(); receiptBuilder.add("Jack's Magic Beans", 4, 4.25); receiptBuilder.add("Princess Peas", 3, 5.1); receiptBuilder.add( "Three Bears Porridge", 1, 14.29); System.out.println(receiptBuilder.build()); } } /* Output: Item Qty Price ---- --- ----- Jack's Magic Be 4 4.25 Princess Peas 3 5.10 Three Bears Por 1 14.29 Tax 2.80 ----- Total 49.39 */ ~~~ 通过传入一个`StringBuilder`对象到`Formatter`的构造器,我们指定了一个容器来构建目标`String`。你也可以通过不同的构造器参数,把结果输出到标准输出,甚至是一个文件里。 正如你所见,通过相当简洁的语法,`Formatter` 提供了对空格与对齐的强大控制能力。在该程序中,为了恰当地控制间隔,格式化字符串被重复利用了多遍。