ArrayList元素被覆盖问题:读取数据库时旧行数据被覆盖原因
问题原因分析
你遇到的这个问题,核心是数组引用复用导致的覆盖问题:你把String[] row的创建放在了while(resultSet.next())循环的外面,这意味着整个循环过程中始终只有同一个数组对象。每次循环你只是修改这个数组里的元素值,然后把同一个数组引用添加到ArrayList中。当循环结束时,List里的所有元素其实都是指向同一个数组的引用,而这个数组最后被修改成了结果集最后一行的数据,所以看起来旧行都被覆盖了。
修复方案
只需要把String[] row的创建移到while循环内部,这样每次遍历结果集的一行时,都会创建一个新的数组对象,添加到List里的就是不同的数组引用,自然不会互相覆盖了:
List<String[]> table = new ArrayList<>(); Statement statement = dbConnection.createStatement(); ResultSet resultSet = statement.executeQuery(query); int columnCount = resultSet.getMetaData().getColumnCount(); // 把row的创建移到while循环内部,每次循环生成新数组 while(resultSet.next()) { String[] row = new String[columnCount]; for(int i = 0; i < columnCount; ++i) { // 注意:ResultSet的列索引从1开始,这里要做偏移处理 row[i] = resultSet.getString(i + 1); } table.add(row); // 添加新的数组引用到List } // 记得手动关闭数据库资源,避免连接泄漏 resultSet.close(); statement.close();
额外优化提示
- ResultSet的列索引是从1开始计数的,原代码里直接用
i获取会抛出索引越界异常,修复后的代码已经调整为i+1,这点要留意。 - 如果使用Java 7及以上版本,推荐用try-with-resources语法自动管理数据库资源,不用手动关闭ResultSet和Statement,更安全简洁:
List<String[]> table = new ArrayList<>(); String query = "你的SQL查询语句"; try (Statement statement = dbConnection.createStatement(); ResultSet resultSet = statement.executeQuery(query)) { int columnCount = resultSet.getMetaData().getColumnCount(); while(resultSet.next()) { String[] row = new String[columnCount]; for(int i = 0; i < columnCount; ++i) { row[i] = resultSet.getString(i + 1); } table.add(row); } } catch (SQLException e) { e.printStackTrace(); }
内容的提问来源于stack exchange,提问作者Mohamed-Sabbagh
相关产品推荐
相关产品推荐

