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); } }
问题分析与解决方法
原插入排序代码仅支持单一整数列排序,无法满足多条件混合(字符串+整数)排序的需求,这是报错的核心原因。我们需要重写排序的比较逻辑,按照性别→年龄→组别的优先级依次比较:
- 性别排序:男性(M)优先于女性(F),若当前元素是F而待插入元素是M,需要将当前元素后移;
- 年龄排序:性别相同时,按年龄升序排列;
- 组别排序:性别和年龄都相同时,按组别字符串的字典序排列。
修改后的插入排序代码
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
相关产品推荐
相关产品推荐

