Java二维数组最后一行全为null问题排查求助
解决Java二维数组最后一整行全为null的问题
我来帮你排查这个问题,从你给出的代码和描述来看,核心问题大概率出在循环次数和实际可读取的文件行数不匹配上,咱们一步步拆解:
问题根源分析
你用了for (int i = 0; i < getFileLines() ; i++)作为外层循环的条件,这里的getFileLines()返回的总行数很可能比实际能成功读取到的有效行数多了一行。比如:
- 文件最后存在一个空行,
getFileLines()把它算成了一行,但实际读取时这行内容为空或者readLine()直接返回null; getFileLines()的统计逻辑有误差,比如统计时包含了文件结束符之类的无效行。
当循环走到最后一次时,bf4.readLine()返回null,这时候readLineString是null,后续的split操作要么抛出空指针异常,要么(如果你悄悄捕获了异常)导致这一轮循环里的readLineArray2D[i][j]完全没被赋值,保持数组初始化时的默认值null,最终就出现了最后一整行都是null的情况。
另外,你给出的数组初始化代码也有明显问题:
secondLineString = bf3.readLine(); secondLineArray = secondLineString.split(";"); readLineArray = readLineString.split(";"); // 这里readLineString还未初始化就调用,会直接报错 readLineArray2D[i][j] = readLineArray[j]; // i和j此时都未定义,根本没法完成数组初始化
正确的二维数组初始化应该先确定行数和列数,再创建数组,比如:
// 先获取列数 secondLineString = bf3.readLine(); secondLineArray = secondLineString.split(";"); int cols = secondLineArray.length; // 再根据文件行数创建二维数组(这里如果getFileLines()不准,还是会有问题) int rows = getFileLines(); readLineArray2D = new String[rows][cols];
修复方案
最稳妥的方式是放弃用固定行数循环,改用while循环读取每一行,直到readLine()返回null,这样能确保循环次数和实际有效行数完全匹配:
// 先获取列数 secondLineString = bf3.readLine(); secondLineArray = secondLineString.split(";"); int cols = secondLineArray.length; // 用List来动态存储每行数据,避免行数不确定的问题 List<String[]> tempList = new ArrayList<>(); String readLineString; while ((readLineString = bf4.readLine()) != null) { String[] readLineArray = readLineString.split(";"); // 加个判断确保每行的列数和第二行一致,避免数组越界 if (readLineArray.length == cols) { tempList.add(readLineArray); } else { // 处理列数不匹配的情况,比如打印日志 System.err.println("行内容列数不匹配:" + readLineString); } } // 把List转成二维数组 String[][] readLineArray2D = tempList.toArray(new String[tempList.size()][]); // 输出结果 System.out.println(Arrays.deepToString(readLineArray2D).replace("], ","]\n"));
如果一定要用for循环,那必须确保getFileLines()返回的是有效行数,并且在循环里判断readLineString是否为null:
int rows = getFileLines(); int cols = secondLineArray.length; readLineArray2D = new String[rows][cols]; for (int i = 0; i < rows ; i++) { readLineString = bf4.readLine(); // 如果读取到null,直接终止循环 if (readLineString == null) { break; } String[] readLineArray = readLineString.split(";"); // 同样判断列数 if (readLineArray.length == cols) { for (int j = 0; j < cols ; j++) { readLineArray2D[i][j] = readLineArray[j]; } } }
额外注意点
- 字符串分割时,
split(";")如果行末尾有分号,会生成一个空字符串元素,你可以根据需求用split(";", -1)或者手动处理空元素; - 一定要处理
readLine()返回null的情况,避免空指针异常; - 检查
getFileLines()的实现,比如是不是用BufferedReader逐行读取统计的?如果是用文件字节数除以平均行高这种方式,很容易出现误差。
内容的提问来源于stack exchange,提问作者Erwin Ivanov
相关产品推荐
相关产品推荐

