需求:
模拟棋盘数据的压缩、持久化与恢复
-
原始数据:一个 11×11 的二维数组模拟棋盘,仅包含 2 个非 0 有效数据(黑棋
1、蓝棋2),其余位置为0。 -
核心转换:将这个稀疏的二维数组压缩为稀疏数组 —— 首行存储原始数组的行数、列数和有效数据数,后续每行存储一个非 0 数据的「行坐标、列坐标、值」。
-
持久化与恢复:
- 把生成的稀疏数组写入文件实现持久化(存档)。
- 再从文件中读取稀疏数组,恢复为原始的 11×11 二维数组(读档),完成棋盘数据的完整闭环。
代码实现:
public class SparseArrayTest02 {
// 定义文件路径常量,便于维护
private static final String SPARSE_ARRAY_FILE_PATH = "D:\JavaTest\SparSearray\sparsearray.txt";
public static void main(String[] args) {
// 1. 创建原始棋盘数组(11x11)
int[][] originalChessboard = createOriginalChessboard();
// 2. 原始数组转换为稀疏数组
int[][] sparseArray = convertToSparseArray(originalChessboard);
System.out.println("=== 生成的稀疏数组 ===");
printArray(sparseArray);
// 3. 将稀疏数组写入文件
writeSparseArrayToFile(sparseArray, SPARSE_ARRAY_FILE_PATH);
// 4. 从文件读取稀疏数组
int[][] readSparseArray = readSparseArrayFromFile(SPARSE_ARRAY_FILE_PATH);
if (readSparseArray != null) {
System.out.println("\n=== 从文件读取的稀疏数组 ===");
printArray(readSparseArray);
}
// 5. 稀疏数组转换回原始数组
int[][] restoredChessboard = convertToOriginalArray(sparseArray);
System.out.println("\n=== 恢复后的原始棋盘数组 ===");
printArray(restoredChessboard);
}
/**
* 功能1:创建原始棋盘数组(11x11,模拟落子)
* @return 初始化后的11x11二维数组
*/
public static int[][] createOriginalChessboard() {
int[][] chessboard = new int[11][11];
chessboard[1][2] = 1; // 模拟1号棋子
chessboard[2][3] = 2; // 模拟2号棋子
return chessboard;
}
/**
* 功能2:原始二维数组转换为稀疏数组
* @param originalArr 原始二维数组(大部分元素为0)
* @return 压缩后的稀疏数组
*/
public static int[][] convertToSparseArray(int[][] originalArr) {
// 步骤1:统计原始数组中非0元素的个数
int validDataCount = countValidData(originalArr);
// 步骤2:初始化稀疏数组(首行存元信息,后续行存非0数据)
int[][] sparseArr = new int[validDataCount + 1][3];
sparseArr[0][0] = originalArr.length; // 原始数组行数
sparseArr[0][1] = originalArr[0].length; // 原始数组列数
sparseArr[0][2] = validDataCount; // 非0元素个数
// 步骤3:填充稀疏数组的非0数据
int sparseRowIndex = 1; // 稀疏数组行索引(从1开始,0行是元信息)
for (int i = 0; i < originalArr.length; i++) {
for (int j = 0; j < originalArr[i].length; j++) {
if (originalArr[i][j] != 0) {
sparseArr[sparseRowIndex][0] = i;
sparseArr[sparseRowIndex][1] = j;
sparseArr[sparseRowIndex][2] = originalArr[i][j];
sparseRowIndex++;
}
}
}
return sparseArr;
}
/**
* 辅助方法:统计原始数组中非0元素的个数
* @param originalArr 原始二维数组
* @return 非0元素数量
*/
public static int countValidData(int[][] originalArr) {
int count = 0;
for (int[] row : originalArr) {
for (int value : row) {
if (value != 0) {
count++;
}
}
}
return count;
}
/**
* 功能3:稀疏数组转换回原始二维数组
* @param sparseArr 稀疏数组
* @return 恢复后的原始二维数组
*/
public static int[][] convertToOriginalArray(int[][] sparseArr) {
// 步骤1:从稀疏数组首行获取原始数组的行列信息,初始化原始数组
int[][] originalArr = new int[sparseArr[0][0]][sparseArr[0][1]];
// 步骤2:填充原始数组的非0数据
for (int i = 1; i < sparseArr.length; i++) {
int row = sparseArr[i][0];
int col = sparseArr[i][1];
int value = sparseArr[i][2];
originalArr[row][col] = value;
}
return originalArr;
}
/**
* 功能4:将稀疏数组写入指定文件(逗号分隔)
* @param sparseArr 待写入的稀疏数组
* @param filePath 文件保存路径
*/
public static void writeSparseArrayToFile(int[][] sparseArr, String filePath) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath))) {
// 逐行写入稀疏数组,每行格式:行,列,值
for (int[] row : sparseArr) {
String line = row[0] + "," + row[1] + "," + row[2];
bw.write(line);
bw.newLine(); // 换行
}
System.out.println("\n稀疏数组已成功写入文件:" + filePath);
} catch (IOException e) {
System.err.println("写入稀疏数组到文件失败!路径:" + filePath);
e.printStackTrace();
}
}
/**
* 功能5:从指定文件读取稀疏数组(逗号分隔)
* @param filePath 文件路径
* @return 读取后的稀疏数组(失败返回null)
*/
public static int[][] readSparseArrayFromFile(String filePath) {
int[][] sparseArr = null;
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
// 步骤1:读取首行(元信息:行数、列数、非0数据数)
String firstLine = br.readLine();
if (firstLine == null) {
System.err.println("文件为空,无法读取稀疏数组!");
return null;
}
String[] metaData = firstLine.split(",");
int originalRows = Integer.parseInt(metaData[0]);
int originalCols = Integer.parseInt(metaData[1]);
int validDataCount = Integer.parseInt(metaData[2]);
// 步骤2:初始化稀疏数组
sparseArr = new int[validDataCount + 1][3];
sparseArr[0][0] = originalRows;
sparseArr[0][1] = originalCols;
sparseArr[0][2] = validDataCount;
// 步骤3:读取后续行,填充非0数据
String line;
int sparseRowIndex = 1;
while ((line = br.readLine()) != null) {
String[] data = line.split(",");
sparseArr[sparseRowIndex][0] = Integer.parseInt(data[0]);
sparseArr[sparseRowIndex][1] = Integer.parseInt(data[1]);
sparseArr[sparseRowIndex][2] = Integer.parseInt(data[2]);
sparseRowIndex++;
}
} catch (IOException e) {
System.err.println("读取稀疏数组文件失败!路径:" + filePath);
e.printStackTrace();
} catch (NumberFormatException e) {
System.err.println("文件内容格式错误!请确保每行是"数字,数字,数字"格式");
e.printStackTrace();
}
return sparseArr;
}
/**
* 功能6:通用数组打印方法(支持稀疏数组/原始数组)
* @param arr 待打印的二维数组
*/
public static void printArray(int[][] arr) {
if (arr == null) {
System.out.println("数组为空,无法打印!");
return;
}
for (int[] row : arr) {
for (int value : row) {
System.out.print(value + "\t");
}
System.out.println();
}
}
}
最终效果: