将JTable转换为JSON时数据顺序错乱问题求助
问题根源与解决办法
这个问题我之前也碰到过,根源很明确:org.json库中的JSONObject默认是无序的!它底层基于哈希表实现,不会保留你插入键值对的顺序。你之前的简单表格列数少,哈希计算后的存储顺序刚好和插入顺序一致,所以输出正常;但当表格包含日期列(列数变多),不同列名的哈希值分布变化,就导致输出顺序和插入顺序脱节了。
下面给你两个靠谱的解决思路:
方案1:用有序模式的JSONObject
org.json从20180813版本开始,给JSONObject加了一个带布尔参数的构造方法,传入true就能开启有序模式,保留插入顺序。修改你的代码很简单,只需要把创建JSONObject的那一行改成:
JSONObject jsonObj = new JSONObject(true); // 开启有序,保证插入顺序和输出顺序一致
这样修改后,你遍历表格列的顺序就是JSON里字段的顺序,不管有没有日期列都不会乱。
方案2:用JSONStringer手动构建(兼容旧版本)
如果你的org.json版本比较老,没有这个有序构造方法,那就用JSONStringer来手动拼接JSON,完全控制字段顺序:
public static void writeTableToFileAsJSON(JTable table, String filePath) { DefaultTableModel model = (DefaultTableModel) table.getModel(); int rowCount = model.getRowCount(); int columnCount = model.getColumnCount(); try (FileWriter fw = new FileWriter(filePath)) { JSONStringer stringer = new JSONStringer(); stringer.array(); // 启动JSON数组 for (int i = 0; i < rowCount; i++) { stringer.object(); // 启动单个JSON对象 for (int j = 1; j < columnCount; j++) { Object value = model.getValueAt(i, j); String columnName = model.getColumnName(j); stringer.key(columnName).value(value); // 按表格列顺序插入键值对 } stringer.endObject(); // 结束当前对象 } stringer.endArray(); // 结束数组 fw.write(stringer.toString()); } catch (IOException | JSONException e) { e.printStackTrace(); // 这里可以根据业务需求替换成日志记录或自定义异常处理 } }
这种方式完全由你掌控顺序,绝对不会出现错乱的情况。
额外小优化
顺便提一句:你代码里的table.setColumnSelectionInterval和table.setRowSelectionInterval其实是多余的,因为你直接从TableModel获取数据,和表格的选中状态无关,删掉这两行能简化代码逻辑。
比如修改后的完整代码(用有序JSONObject):
public static void writeTableToFileAsJSON(JTable table, String filePath) { DefaultTableModel model = (DefaultTableModel) table.getModel(); int rowCount = model.getRowCount(); int columnCount = model.getColumnCount(); boolean firstRow = true; try (FileWriter fw = new FileWriter(filePath)) { fw.write("["); for (int i = 0; i < rowCount; i++) { JSONObject jsonObj = new JSONObject(true); // 启用有序模式 for (int j = 1; j < columnCount; j++) { Object value = model.getValueAt(i, j); String columnName = model.getColumnName(j); jsonObj.put(columnName, value); } fw.write(firstRow ? jsonObj.toString() : ("," + jsonObj.toString())); firstRow = false; } fw.write("]"); } catch (IOException | JSONException e) { e.printStackTrace(); // 按需处理异常 } }
内容的提问来源于stack exchange,提问作者Morgan
相关产品推荐
相关产品推荐

