如何用 Java 二维数组格式化输出表格数据

本文教你使用二维字符串数组存储国家与首都数据,并通过动态计算列宽、封装辅助方法实现对齐美观的表格输出,避免简单循环导致的错位问题。

在 Java 中,用二维数组模拟“表格”是一种常见且实用的入门实践(注意:此处的“table”并非 Java 特定术语,而是指逻辑上的行列结构)。初学者常遇到的核心难点不是数据存储,而是格式化输出——即让 Country 和 Capital 两列严格对齐,形成视觉清晰的表格效果。直接使用 System.out.println() 逐行打印每个元素会导致列宽不一致;而 printf 配合动态空格填充才是专业解法。

下面是一个结构清晰、职责分离的实现方案:

public class Arrays39 {
    public static void main(String[] args) {
        String[][] countries = {
            {"Mexico", "DF"},
            {"Guatemala", "Guatemala City"},
            {"El Salvador", "El Salvador"},
            {"Russia", "Moscow"}
        };
        int maxCountryLength = maxPadding(countries);
        generateTable(countries, maxCountryLength);
    }

    // 主输出方法:按固定列宽格式化打印表头与每行数据
    public static void generateTable(String[][] data, int padding) {
        // 表头:Country 后补足空格,再拼接 Capital
        System.out.printf("Country%sCapital%n", " ".repeat(Math.max(0, padding - "Country".length() + 1)));
        for (String[] row : data) {
            // 每行:国家名 + 动态空格 + 首都名
            int spacesNeeded = Math.max(0, padding - row[0].length() + 1);
            System.out.printf("%s%s%s%n", row[0], " ".repeat(spacesNeeded), row[1]);
        }
    }

    // 辅助方法:计算第一列(国家名)的最大字符长度
    private static int maxPadding(String[][] data) {
        int max = 0;
        for (String[] row : data) {
            if (row[0].length() > max) {
                max = row[0].length();
            }
        }
        return max;
    }
}

关键改进点说明:

  • 职责分离:maxPadding() 专注计算列宽,generateTable() 专注渲染,主方法仅协调流程,大幅提升可读性与可维护性;
  • 动态对齐:利用 String.repeat(n)(Java 11+)替代手动 StringBuilder 循环拼接空格,代码更简洁安全;
  • 表头对齐:表头 "Country" 的右侧空格数 = maxCountryLength - "Country".length() + 1,确保其与数据列右边界对齐;
  • 健壮性增强:Math.max(0, ...) 防止负数空格导致异常。

⚠️ 注意事项:

  • 若需兼容 Java 8 或更低版本,请将 " ".repeat(n) 替换为 new String(new char[n]).replace('\0', ' ');
  • 实际项目中建议改用 List> 或自定义类(如 CountryRecord)提升类型安全与扩展性;
  • 此方案适用于小规模静态数据;处理大量数据或复杂格式时,推荐使用 Apache Commons Text 的 StringEscapeUtils 或专用表格库(如 picocli 的 TablePrinter)。

掌握这种“数据结构 + 格式化逻辑分离”的思维模式,是你从语法练习迈向工程化编码的重要一步。