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

Java中按性别(男→女)、年龄、组别对CSV举重运动员数据排序问题

解决举重运动员CSV数据的多条件排序问题

我有一个存储举重运动员数据的CSV文件,需要按性别(男性优先,再到女性)、年龄升序、组别字典序的规则对数据排序。自己编写了代码但运行报错,以下是示例数据、读取CSV的Java代码和插入排序代码,寻求解决方法。

示例CSV数据

MeetID,Name,Gender,Age,Division
0,Dawn Bogart,F,42,Open Senior
0,Destiny Dula,F,18,Teen 
0,Jessica Jenkins,F,32,Open Senior
1,Emanuel Moldovan,M,21,Novice
1,Jared Morey,M,36,MPF
5,Ryan Daining,M,25,Open

读取CSV的Java代码

public void readFile(String fileName) {
    try {
        File theFile = new File(fileName);
        System.out.println("File path: " + theFile.getAbsolutePath());
        if (!theFile.exists()) {
            System.out.println("File not found!");
            return;
        }
        Scanner myReader = new Scanner(theFile);
        boolean firstLine = true;

        while (myReader.hasNextLine()) {
            String data = myReader.nextLine();
            System.out.println("Read line: " + data); // 调试输出

            if (firstLine) {
                firstLine = false;
            } else {
                String[] datas = data.split(",");
                myData.add(datas);
            }
        }
        myReader.close();
    } catch (FileNotFoundException e) {
        System.out.println("ERROR: " + e.getMessage());
    }

    System.out.println("Total Data: " + myData.size());
}

原插入排序代码

private void insertionSort(ArrayList<String[]> data, int columnIndex) {
    for (int i = 1; i < data.size(); i++) {
        String[] key = data.get(i);
        int j = i - 1;

        while (j >= 0 && Integer.parseInt(data.get(j)[columnIndex]) > Integer.parseInt(key[columnIndex])) {
            data.set(j + 1, data.get(j));
            j = j - 1;
        }
        data.set(j + 1, key);
    }
}

问题分析与解决方法

原插入排序代码仅支持单一整数列排序,无法满足多条件混合(字符串+整数)排序的需求,这是报错的核心原因。我们需要重写排序的比较逻辑,按照性别→年龄→组别的优先级依次比较:

  1. 性别排序:男性(M)优先于女性(F),若当前元素是F而待插入元素是M,需要将当前元素后移;
  2. 年龄排序:性别相同时,按年龄升序排列;
  3. 组别排序:性别和年龄都相同时,按组别字符串的字典序排列。

修改后的插入排序代码

private void insertionSortAthleteData(ArrayList<String[]> data) {
    for (int i = 1; i < data.size(); i++) {
        String[] key = data.get(i);
        int j = i - 1;

        // 多条件比较:性别→年龄→组别
        while (j >= 0 && shouldMove(data.get(j), key)) {
            data.set(j + 1, data.get(j));
            j--;
        }
        data.set(j + 1, key);
    }
}

// 判断当前元素是否需要向后移动(即key应该排在当前元素前面)
private boolean shouldMove(String[] current, String[] key) {
    // 1. 比较性别:M优先于F,若当前是F,key是M → current需要后移
    char currentGender = current[2].charAt(0);
    char keyGender = key[2].charAt(0);
    if (currentGender != keyGender) {
        return currentGender == 'F' && keyGender == 'M';
    }

    // 2. 性别相同,比较年龄(升序)
    int currentAge = Integer.parseInt(current[3]);
    int keyAge = Integer.parseInt(key[3]);
    if (currentAge != keyAge) {
        return currentAge > keyAge;
    }

    // 3. 年龄相同,比较组别(字典序)
    String currentDiv = current[4].trim(); // 去除可能的空格
    String keyDiv = key[4].trim();
    return currentDiv.compareTo(keyDiv) > 0;
}

调用示例

在读取完CSV数据后,直接调用修改后的排序方法即可:

// 假设myData是存储运动员数据的ArrayList<String[]>
insertionSortAthleteData(myData);

// 排序后输出验证
for (String[] athlete : myData) {
    System.out.println(String.join(",", athlete));
}

额外注意事项

  • 若CSV中存在年龄非数字的情况,需要在Integer.parseInt时增加异常处理,避免运行时报错;
  • 若组别字段存在前后空格,建议在读取数据时就进行trim()处理,避免排序结果不符合预期;
  • 原CSV读取代码中,data.split(",")在字段包含逗号时会出错,若有这种场景,建议使用专业的CSV解析逻辑处理。

内容的提问来源于stack exchange,提问作者Ikhsan Nur pratama

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 23:47:02