如何用String.format在Java中实现字符串列对齐输出?
实现列对齐的文件输出方案
你的问题根源在于直接用空格分隔字段,不同长度的字段会导致列错位——毕竟有的IP是192.168.1.1,有的可能是10.0.0.1,长度不一样,单纯加空格自然没法对齐。要解决这个问题,核心思路是给每个字段分配固定的显示宽度,长度不够的用空格自动填充,这样每列就能垂直对齐了。
具体实现步骤
我给你两种方案,一种是固定宽度快速实现,另一种是动态适配字段最长长度,更灵活:
方案1:固定宽度格式化(快速上手)
直接用String.format()定义每行的格式模板,给每个字段指定宽度和对齐方式(左对齐用-前缀,数字也可以选择右对齐)。修改你的方法如下:
private static StringBuilder appendStrings(String pro, List<ProcConfig> list, StringBuilder sb) { // 定义格式模板:每个字段的宽度根据实际业务调整,%-8s表示左对齐占8个字符宽度 String lineTemplate = "%-8s %-5d %-10s %-18s %-6d %-8d %-20s%n"; for (ProcConfig pc : list) { // 用格式化生成对齐的行,%n自动适配系统换行符 String alignedLine = String.format(lineTemplate, pro, pc.getNo(), pc.getId(), pc.getAddress(), pc.getPort(), pc.getNumPorts(), pc.getName()); sb.append(alignedLine); } sb.append(System.getProperty("line.separator")); return sb; }
这里的参数说明:
%-8s:左对齐,占8个字符宽度的字符串类型字段%-5d:左对齐,占5个字符宽度的整数类型字段(如果你的no是数字的话)%n:替代System.getProperty("line.separator"),自动适配Windows/Linux的换行符
你可以根据实际字段的长度调整模板里的数字,比如IP地址最长是15位(255.255.255.255),所以给18位宽度留一点余量,避免拥挤。
方案2:动态适配字段最长长度(更灵活)
如果某些字段(比如name)的长度差异很大,固定宽度可能会浪费空间或者截断内容,这时候可以先遍历列表,计算每个字段的最大长度,再动态生成格式模板:
private static StringBuilder appendStrings(String pro, List<ProcConfig> list, StringBuilder sb) { if (list.isEmpty()) { return sb; } // 计算各字段的最大长度 int maxProLength = pro.length(); int maxNoLength = list.stream().mapToInt(pc -> String.valueOf(pc.getNo()).length()).max().orElse(5); int maxIdLength = list.stream().mapToInt(pc -> pc.getId().length()).max().orElse(10); int maxAddressLength = list.stream().mapToInt(pc -> pc.getAddress().length()).max().orElse(18); int maxPortLength = list.stream().mapToInt(pc -> String.valueOf(pc.getPort()).length()).max().orElse(6); int maxNumPortsLength = list.stream().mapToInt(pc -> String.valueOf(pc.getNumPorts()).length()).max().orElse(8); int maxNameLength = list.stream().mapToInt(pc -> pc.getName().length()).max().orElse(20); // 动态生成格式模板,每个字段宽度取最大长度+2(留一点间隔) String lineTemplate = String.format("%%-%ds %%-%dd %%-%ds %%-%ds %%-%dd %%-%dd %%-%ds%%n", maxProLength + 2, maxNoLength + 2, maxIdLength + 2, maxAddressLength + 2, maxPortLength + 2, maxNumPortsLength + 2, maxNameLength); for (ProcConfig pc : list) { String alignedLine = String.format(lineTemplate, pro, pc.getNo(), pc.getId(), pc.getAddress(), pc.getPort(), pc.getNumPorts(), pc.getName()); sb.append(alignedLine); } sb.append(System.getProperty("line.separator")); return sb; }
这种方式会根据实际数据自动调整每列的宽度,既不会浪费空间,也不会因为字段太长导致截断。
小提示
- 如果是数字类型的字段(比如port),也可以选择右对齐(去掉
-前缀,比如%6d),这样数字会靠右对齐,看起来更整齐 - 测试的时候可以打印几行看看效果,微调宽度数值,找到最舒服的显示比例
内容的提问来源于stack exchange,提问作者flash
相关产品推荐
相关产品推荐

