在Java程序开发中,我们常常会把结构化的数据存储在二维数组中,之后需要将这些数据以表格的形式输出到控制台,让展示效果更清晰。但如果不做处理,直接输出二维数组的元素,往往会出现列不对齐、内容参差不齐的问题,这时候就需要通过字符串格式化来实现对齐效果。
二维数组的基本定义与初始化
首先我们需要了解二维数组的定义方式,二维数组可以看作是一个存储一维数组的容器,每一个一维数组代表表格的一行数据。以下是定义并初始化一个存储学生信息的二维数组的示例:
public class TableOutputDemo {
public static void main(String[] args) {
// 定义二维数组,每行存储学生姓名、年龄、成绩
String[][] studentData = {
{"张三", "20", "89.5"},
{"李四", "21", "92.0"},
{"王五", "19", "76.5"},
{"赵六", "22", "88.0"}
};
}
}
实现左对齐的表格输出
左对齐是表格输出中最常见的对齐方式,我们可以通过String.format方法指定每个单元格的宽度,不足的部分用空格补齐。首先需要遍历二维数组的每一行,再遍历每一行中的每个元素,按照指定格式拼接后输出。
public class TableOutputDemo {
public static void main(String[] args) {
String[][] studentData = {
{"张三", "20", "89.5"},
{"李四", "21", "92.0"},
{"王五", "19", "76.5"},
{"赵六", "22", "88.0"}
};
// 定义表头
String[] headers = {"姓名", "年龄", "成绩"};
// 每个单元格的宽度设置为10个字符
int cellWidth = 10;
// 输出表头
for (String header : headers) {
// %-10s 表示左对齐,宽度为10
System.out.print(String.format("%-" + cellWidth + "s", header));
}
System.out.println();
// 输出分隔线
for (int i = 0; i < headers.length * cellWidth; i++) {
System.out.print("-");
}
System.out.println();
// 输出二维数组中的数据
for (String[] row : studentData) {
for (String cell : row) {
System.out.print(String.format("%-" + cellWidth + "s", cell));
}
System.out.println();
}
}
}
实现右对齐的表格输出
如果需要实现右对齐的效果,只需要调整格式化字符串的参数即可,把%-10s改为%10s,去掉负号就表示右对齐。
public class TableOutputDemo {
public static void main(String[] args) {
String[][] studentData = {
{"张三", "20", "89.5"},
{"李四", "21", "92.0"},
{"王五", "19", "76.5"},
{"赵六", "22", "88.0"}
};
String[] headers = {"姓名", "年龄", "成绩"};
int cellWidth = 10;
// 输出右对齐的表头
for (String header : headers) {
// %10s 表示右对齐,宽度为10
System.out.print(String.format("%" + cellWidth + "s", header));
}
System.out.println();
for (int i = 0; i < headers.length * cellWidth; i++) {
System.out.print("-");
}
System.out.println();
// 输出右对齐的数据
for (String[] row : studentData) {
for (String cell : row) {
System.out.print(String.format("%" + cellWidth + "s", cell));
}
System.out.println();
}
}
}
自适应列宽的对齐表格实现
上面的示例中我们固定了每个单元格的宽度,但实际场景中不同列的内容长度可能差异很大,固定宽度会导致空间浪费或者内容被截断。这时候可以先遍历二维数组和表头,计算出每一列的最大宽度,再根据这个宽度进行格式化输出。
import java.util.Arrays;
public class TableOutputDemo {
public static void main(String[] args) {
String[][] studentData = {
{"张三", "20", "89.5"},
{"李四", "21", "92.0"},
{"王五五", "19", "76.5"},
{"赵六", "22", "88.0"}
};
String[] headers = {"姓名", "年龄", "成绩"};
// 列数
int columnCount = headers.length;
// 存储每一列的最大宽度
int[] columnWidths = new int[columnCount];
// 先计算表头每列的宽度
for (int i = 0; i < columnCount; i++) {
columnWidths[i] = headers[i].length();
}
// 遍历二维数组,更新每列的最大宽度
for (String[] row : studentData) {
for (int i = 0; i < columnCount; i++) {
int cellLength = row[i].length();
if (cellLength > columnWidths[i]) {
columnWidths[i] = cellLength;
}
}
}
// 输出表头,左对齐
for (int i = 0; i < columnCount; i++) {
System.out.print(String.format("%-" + (columnWidths[i] + 2) + "s", headers[i]));
}
System.out.println();
// 输出分隔线
int totalWidth = Arrays.stream(columnWidths).sum() + columnCount * 2;
for (int i = 0; i < totalWidth; i++) {
System.out.print("-");
}
System.out.println();
// 输出数据,左对齐
for (String[] row : studentData) {
for (int i = 0; i < columnCount; i++) {
System.out.print(String.format("%-" + (columnWidths[i] + 2) + "s", row[i]));
}
System.out.println();
}
}
}
注意事项
- 如果二维数组中存储的是数字类型,需要先转换为字符串再进行格式化,否则会出现格式错误。
- 中文字符在部分控制台中占用的宽度可能和英文字符不同,如果需要更精准的对齐,可以针对中文字符做额外的宽度计算。
- 如果表格内容过长,需要考虑控制台的换行问题,避免一行内容超出控制台宽度。