如何在Java中排序一个列表并利用其索引变化同步排序另外两个关联列表
我懂这种痛点!Python里用DataFrame确实能一键搞定列排序联动,但Java没有这种现成的工具,不过我们有两种靠谱的方法来实现你要的效果,让bt和prc跟着at的排序走:
方法一:基于索引排序(快速实现)
核心思路是:先确定at排序后的索引顺序,再用这个顺序重新提取三个列表的元素。这种方法不需要创建新类,适合快速解决问题。
import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; public class SyncSortExample { public static void main(String[] args) { // 初始化你的三个列表 ArrayList<Integer> at = new ArrayList<>(Arrays.asList(2, 0, 2, 3, 4)); ArrayList<Integer> bt = new ArrayList<>(Arrays.asList(2, 1, 3, 5, 4)); ArrayList<String> prc = new ArrayList<>(Arrays.asList("p1", "p2", "p3", "p4", "p5")); // 1. 创建索引列表,存储原始位置的索引 List<Integer> indices = new ArrayList<>(); for (int i = 0; i < at.size(); i++) { indices.add(i); } // 2. 根据at中对应元素的大小排序索引 Collections.sort(indices, (i1, i2) -> Integer.compare(at.get(i1), at.get(i2))); // 3. 根据排序后的索引,重新构建三个列表 ArrayList<Integer> sortedAt = new ArrayList<>(); ArrayList<Integer> sortedBt = new ArrayList<>(); ArrayList<String> sortedPrc = new ArrayList<>(); for (int idx : indices) { sortedAt.add(at.get(idx)); sortedBt.add(bt.get(idx)); sortedPrc.add(prc.get(idx)); } // 验证结果 System.out.println("排序后的at: " + sortedAt); // 输出 [0, 2, 2, 3, 4] System.out.println("排序后的bt: " + sortedBt); // 输出 [1, 2, 3, 5, 4] System.out.println("排序后的prc: " + sortedPrc); // 输出 [p2, p1, p3, p4, p5] } }
说明
- Java的
Collections.sort是稳定排序(从Java 7开始使用Timsort),所以当at中有重复元素时,原始列表中靠前的元素会在排序后依然保持相对顺序,完全符合你的需求。 - 这种方法不需要修改原始列表,而是生成新的排序后列表,避免了数据污染。
方法二:面向对象封装(更推荐长期维护)
如果你的业务场景后续可能扩展(比如增加更多和进程相关的属性),更推荐把at、bt、prc封装成一个实体类,直接对实体类列表排序,这样代码更清晰,也更符合Java的面向对象设计思想。
import java.util.ArrayList; import java.util.Collections; import java.util.List; // 定义进程实体类,封装相关属性 class Process { int arrivalTime; // 对应你的at int burstTime; // 对应你的bt String name; // 对应你的prc public Process(int arrivalTime, int burstTime, String name) { this.arrivalTime = arrivalTime; this.burstTime = burstTime; this.name = name; } } public class ObjectOrientedSort { public static void main(String[] args) { // 初始化进程列表 List<Process> processes = new ArrayList<>(); processes.add(new Process(2, 2, "p1")); processes.add(new Process(0, 1, "p2")); processes.add(new Process(2, 3, "p3")); processes.add(new Process(3, 5, "p4")); processes.add(new Process(4, 4, "p5")); // 根据 arrivalTime(即at)排序 Collections.sort(processes, (p1, p2) -> Integer.compare(p1.arrivalTime, p2.arrivalTime)); // 提取排序后的各个列表(如果需要单独的列表的话) ArrayList<Integer> sortedAt = new ArrayList<>(); ArrayList<Integer> sortedBt = new ArrayList<>(); ArrayList<String> sortedPrc = new ArrayList<>(); for (Process p : processes) { sortedAt.add(p.arrivalTime); sortedBt.add(p.burstTime); sortedPrc.add(p.name); } // 验证结果 System.out.println("排序后的at: " + sortedAt); System.out.println("排序后的bt: " + sortedBt); System.out.println("排序后的prc: " + sortedPrc); } }
说明
- 这种方式把相关数据聚合在一起,逻辑更清晰,后续如果需要添加新属性(比如优先级、完成时间等),只需要修改
Process类即可,不需要调整排序逻辑。 - 排序时直接操作实体类,避免了多个列表同步的潜在错误。
内容的提问来源于stack exchange,提问作者Roman Regmi
相关产品推荐
相关产品推荐

