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

如何使用Comparator按指定规则对Order对象列表进行排序

实现方案

方案1:自定义Comparator实现全局排序

该方案符合你要求的使用Comparator排序的需求,实现前需要先预计算每个订单在所属客户下的uniqueId排名(最大uniqueId排名为0,第二大为1,依此类推),再基于排名完成排序。
首先需要给Order类补充getCustomerId()、getUniqueId()两个getter方法,用于读取私有属性。

预计算排名映射代码

// 按客户ID分组
Map<Long, List<Order>> customerGroup = orderList.stream()
        .collect(Collectors.groupingBy(Order::getCustomerId));
// 构建 客户ID->(uniqueId->排名) 的映射
Map<Long, Map<Long, Integer>> rankMapping = new HashMap<>();
for (var entry : customerGroup.entrySet()) {
    Long customerId = entry.getKey();
    List<Order> orders = entry.getValue();
    // 单个客户的订单按uniqueId降序排列
    orders.sort((a, b) -> Long.compare(b.getUniqueId(), a.getUniqueId()));
    Map<Long, Integer> uidRank = new HashMap<>();
    for (int i = 0; i < orders.size(); i++) {
        uidRank.put(orders.get(i).getUniqueId(), i);
    }
    rankMapping.put(customerId, uidRank);
}

Comparator实现代码

Comparator<Order> orderComparator = (o1, o2) -> {
    // 先取两个订单的排名
    Integer rank1 = rankMapping.get(o1.getCustomerId()).get(o1.getUniqueId());
    Integer rank2 = rankMapping.get(o2.getCustomerId()).get(o2.getUniqueId());
    // 排名越小越靠前
    int rankCompare = Integer.compare(rank1, rank2);
    if (rankCompare != 0) {
        return rankCompare;
    }
    // 同排名按客户ID升序排列,和示例输出顺序一致
    return Long.compare(o1.getCustomerId(), o2.getCustomerId());
};
// 执行排序
orderList.sort(orderComparator);

方案2:更优的按位拼接实现(推荐)

该方案不需要对整个列表做全局排序,时间复杂度更低,尤其适合数据量较大的场景。
实现逻辑:先按客户分组,每组内按uniqueId降序排序,再按位依次取每个组的第N个元素拼接成最终结果,和你要求的输出规则完全匹配。

实现代码

// 按客户ID分组
Map<Long, List<Order>> customerGroup = orderList.stream()
        .collect(Collectors.groupingBy(Order::getCustomerId));
// 每个客户的订单按uniqueId降序排序
List<List<Order>> sortedPerCustomer = new ArrayList<>();
for (List<Order> orders : customerGroup.values()) {
    orders.sort((a, b) -> Long.compare(b.getUniqueId(), a.getUniqueId()));
    sortedPerCustomer.add(orders);
}
// 按位拼接得到最终结果
List<Order> result = new ArrayList<>();
int orderCountPerUser = sortedPerCustomer.get(0).size();
for (int i = 0; i < orderCountPerUser; i++) {
    for (List<Order> userOrders : sortedPerCustomer) {
        result.add(userOrders.get(i));
    }
}

优势说明

如果每个客户的订单数固定为k,总订单数为n,该方案的时间复杂度为O(n)(每组排序的O(k log k)为常数级),远优于全局排序的O(n log n)。

注意事项
  • 上述实现默认所有客户的订单数量一致,和题目给出的场景匹配,如果不同客户订单数不同,按位拼接时需要增加长度判断避免数组越界。
  • 如果同一客户存在重复的uniqueId,需要调整排名逻辑,可新增其他维度(比如订单生成时间)区分排名,或者允许重复排名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 05:21:02