如何根据另一个列表的顺序对Java对象列表按指定属性排序?
根据指定列表的属性值排序对象列表
当然可以实现这种排序逻辑,核心思路是以指定列表中元素的索引作为排序优先级,通过对比对象属性在该列表中的位置来完成排序。以下是针对你场景的具体实现方案:
前提说明
假设CustomObject类提供了获取model属性的方法getModel(),例如:
public class CustomObject { private String model; // 其他属性、构造方法省略 public String getModel() { return model; } }
高效实现步骤
构建索引映射表
先把models列表转换为model字符串 -> 索引的Map,避免排序时反复调用indexOf()(将时间复杂度从O(n²)优化到O(n log n)):Map<String, Integer> modelOrderMap = new HashMap<>(); for (int i = 0; i < models.size(); i++) { modelOrderMap.put(models.get(i), i); }执行排序
根据需求选择排序方式,同时处理两个列表长度不同的情况(即部分CustomObject的model不在models列表中):
方式一:直接修改原列表(Collections.sort)
Collections.sort(customObjects, (o1, o2) -> { Integer index1 = modelOrderMap.get(o1.getModel()); Integer index2 = modelOrderMap.get(o2.getModel()); // 规则:不在models中的元素排在最后;若需排在前面,调换return 1和return -1即可 if (index1 == null) return 1; if (index2 == null) return -1; return index1.compareTo(index2); });
方式二:生成新的排序后列表(Stream API,Java 8+)
List<CustomObject> sortedCustomObjects = customObjects.stream() .sorted((o1, o2) -> { Integer idx1 = modelOrderMap.get(o1.getModel()); Integer idx2 = modelOrderMap.get(o2.getModel()); if (idx1 == null) return 1; if (idx2 == null) return -1; return idx1.compareTo(idx2); }) .collect(Collectors.toList());
可选:过滤掉不在models中的元素
如果不需要保留model不在models里的对象,可以添加过滤逻辑:
List<CustomObject> filteredSortedList = customObjects.stream() .filter(obj -> modelOrderMap.containsKey(obj.getModel())) .sorted((o1, o2) -> { Integer idx1 = modelOrderMap.get(o1.getModel()); Integer idx2 = modelOrderMap.get(o2.getModel()); return idx1.compareTo(idx2); }) .collect(Collectors.toList());
验证结果
针对你给出的示例数据,执行排序后,customObjects会按照models列表中x2 -> x5 -> x1 -> x4 -> x3的顺序排列,与预期结果完全一致。
内容的提问来源于stack exchange,提问作者Dave Hester
相关产品推荐
相关产品推荐

