You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JTable按平均分排序后如何正确生成学生排名?

解决JTable排序后排名不正确的问题

嗨,我来帮你分析下问题所在,并且给出修复方案:

核心问题根源

你使用TableRowSorter实现的是**视图层(JTable显示的行)的排序,但你的positionInsert方法直接操作的是底层TableModel(原始数据顺序)**的行。这就导致你设置的排名是按照原始数据的顺序生成的,和JTable排序后显示的行顺序完全不匹配,自然出现排名错误。

修复后的代码

你需要通过JTable提供的索引转换方法,将视图层的行索引映射到底层模型的行索引,这样才能给排序后显示的每一行正确设置排名:

// 按平均分列排序JTable
public void checkPosition(){
    // 隐藏序号列
    jTable1.getColumnModel().getColumn(0).setMinWidth(0);
    jTable1.getColumnModel().getColumn(0).setMaxWidth(0);
    jTable1.getColumnModel().getColumn(0).setWidth(0);
    
    TableRowSorter<TableModel> sorter = new TableRowSorter<>(jTable1.getModel());
    jTable1.setRowSorter(sorter);
    List<RowSorter.SortKey> sortKeys = new ArrayList<>();
    // 按平均分列(倒数第二列)降序排序
    sortKeys.add(new RowSorter.SortKey(jTable1.getColumnCount()-2, SortOrder.DESCENDING));
    sorter.setSortKeys(sortKeys);
    
    // 确保排序完成后再插入排名
    sorter.sort();
    positionInsert();
}

public void positionInsert(){
    // 在最后一列“position”插入排名
    int pos = 1;
    DefaultTableModel model = (DefaultTableModel)jTable1.getModel();
    // 遍历视图层的行(排序后的显示顺序)
    for(int viewRow = 0; viewRow < jTable1.getRowCount(); viewRow++){
        // 将视图行索引转换为对应的模型行索引
        int modelRow = jTable1.convertRowIndexToModel(viewRow);
        // 给模型中对应的行设置排名
        model.setValueAt(pos, modelRow, jTable1.getColumnCount()-1);
        pos++;
    }
}

关键细节解释

  1. 索引转换:jTable1.convertRowIndexToModel(viewRow)方法的作用是把当前JTable显示的第viewRow行,映射到底层TableModel中对应的行索引。这样就能保证我们给排序后显示的每一行,正确地设置对应的排名。
  2. 提前获取模型:把DefaultTableModel model = (DefaultTableModel)jTable1.getModel();移到循环外面,避免每次循环都重复获取模型,提升效率。
  3. 确保排序完成:调用sorter.sort()显式触发排序,避免在排序还没完成时就执行排名插入操作。

额外优化(可选)

如果需要处理同分同排名的场景(比如两个学生平均分相同,排名应该一致),你可以在遍历视图行时,先获取当前行和上一行的平均分进行对比:

public void positionInsert(){
    int pos = 1;
    DefaultTableModel model = (DefaultTableModel)jTable1.getModel();
    // 记录上一行的平均分
    double prevScore = -1;
    int sameCount = 0;
    
    for(int viewRow = 0; viewRow < jTable1.getRowCount(); viewRow++){
        int modelRow = jTable1.convertRowIndexToModel(viewRow);
        double currentScore = Double.parseDouble(model.getValueAt(modelRow, jTable1.getColumnCount()-2).toString());
        
        if(viewRow > 0 && currentScore == prevScore){
            // 和上一行分数相同,排名不变
            sameCount++;
        } else {
            // 分数不同,更新排名
            pos += sameCount;
            sameCount = 0;
        }
        
        model.setValueAt(pos, modelRow, jTable1.getColumnCount()-1);
        prevScore = currentScore;
    }
}

内容的提问来源于stack exchange,提问作者Heizy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:58:45