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

如何按指定规则排序含普通与赠品条目的OrderEntry列表?

订单条目排序问题

OrderEntry 对象定义

@Data
public static class OrderEntry {
    private String entryNumber;
    // giftFlag=0 表示该OrderEntry为普通条目
    // giftFlag=1 表示该OrderEntry为赠品条目
    private Integer giftFlag;
    private List<String> sourceEntryNumbers;
}

giftFlag=0 表示该OrderEntry为普通条目
giftFlag=1 表示该OrderEntry为赠品条目

现有一个包含普通条目和赠品条目的OrderEntry列表,需按指定规则排序:普通条目在前,若普通条目关联赠品条目,则赠品条目紧随其后。

更新说明

需实现的排序规则为:普通条目按entryNumber排序,对应赠品条目紧跟其关联的普通条目之后。

限制条件:该需求不属于多字段排序,且不能使用Comparator的compare和thenComparing方法。

测试示例代码

@Test
public void testSort() {
    OrderEntry orderEntry1 = new OrderEntry();
    orderEntry1.setEntryNumber("1");
    orderEntry1.setGiftFlag(0);
    OrderEntry orderEntry2 = new OrderEntry();
    orderEntry2.setEntryNumber("2");
    orderEntry2.setGiftFlag(0);
    OrderEntry orderEntry3 = new OrderEntry();
    orderEntry3.setGiftFlag(1);
    // 表示该赠品条目由orderEntry1和orderEntry2生成
    orderEntry3.setSourceEntryNumbers(Arrays.asList("1", "2"));

    OrderEntry orderEntry4 = new OrderEntry();
    orderEntry4.setEntryNumber("3");
    orderEntry4.setGiftFlag(0);
    OrderEntry orderEntry5 = new OrderEntry();
    orderEntry5.setGiftFlag(1);
    // 表示该赠品条目由orderEntry3生成
    orderEntry5.setSourceEntryNumbers(Arrays.asList("3"));

    OrderEntry orderEntry6 = new OrderEntry();
    orderEntry6.setEntryNumber("4");
    orderEntry6.setGiftFlag(0);
    OrderEntry orderEntry7 = new OrderEntry();
    orderEntry7.setGiftFlag(1);
    // 表示该赠品条目由orderEntry4生成
    orderEntry7.setSourceEntryNumbers(Arrays.asList("4"));

    OrderEntry orderEntry8 = new OrderEntry();
    orderEntry8.setEntryNumber("8");
    orderEntry8.setGiftFlag(0);

    List<OrderEntry> list = new ArrayList<>();
    list.add(orderEntry1);
    list.add(orderEntry2);
    list.add(orderEntry4);
    list.add(orderEntry6);
    list.add(orderEntry3);
    list.add(orderEntry5);
    list.add(orderEntry7);
    list.add(orderEntry8);

    System.out.println(JSON.toJSONString(list));
    // 当前输出:
    // [{"entryNumber":"1","giftFlag":0},{"entryNumber":"2","giftFlag":0},{"entryNumber":"3","giftFlag":0},{"entryNumber":"4","giftFlag":0},{"giftFlag":1,"sourceEntryNumbers":["1","2"]},{"giftFlag":1,"sourceEntryNumbers":["3"]},{"giftFlag":1,"sourceEntryNumbers":["4"]},{"entryNumber":"8","giftFlag":0}]

    // 预期输出:
    // [{"entryNumber":"1","giftFlag":0},{"entryNumber":"2","giftFlag":0},{"giftFlag":1,"sourceEntryNumbers":["1","2"]},{"entryNumber":"3","giftFlag":0},{"giftFlag":1,"sourceEntryNumbers":["3"]},{"entryNumber":"4","giftFlag":0},{"giftFlag":1,"sourceEntryNumbers":["4"]},{"entryNumber":"8","giftFlag":0}]
}

解决方案

可以通过构建新有序列表的方式实现需求,避开Comparator的compare和thenComparing方法,步骤如下:

  1. 分离普通条目与赠品条目
    遍历原列表,将普通条目(giftFlag=0)和赠品条目(giftFlag=1)分别存入两个集合。

  2. 排序普通条目
    对普通条目集合按entryNumber进行自然排序,这里直接手动实现字符串比较逻辑,避免使用Comparator的规范方法。

  3. 构建赠品关联映射
    创建映射表,key为普通条目的entryNumber,value为关联的赠品条目列表;同时用集合记录已添加的赠品,避免重复加入。

  4. 组装最终有序列表
    依次将排序后的普通条目加入新列表,每加入一个普通条目,就检查映射表中是否有对应的赠品,若有且未添加过,则将赠品加入列表。

具体实现代码

// 1. 分离普通条目和赠品条目
List<OrderEntry> normalEntries = new ArrayList<>();
List<OrderEntry> giftEntries = new ArrayList<>();
for (OrderEntry entry : list) {
    if (0 == entry.getGiftFlag()) {
        normalEntries.add(entry);
    } else {
        giftEntries.add(entry);
    }
}

// 2. 对普通条目按entryNumber排序
normalEntries.sort((a, b) -> a.getEntryNumber().compareTo(b.getEntryNumber()));

// 3. 构建赠品关联映射,同时记录已处理的赠品
Map<String, List<OrderEntry>> giftMap = new HashMap<>();
Set<OrderEntry> addedGifts = new HashSet<>();
for (OrderEntry gift : giftEntries) {
    for (String source : gift.getSourceEntryNumbers()) {
        giftMap.computeIfAbsent(source, k -> new ArrayList<>()).add(gift);
    }
}

// 4. 组装最终有序列表
List<OrderEntry> sortedList = new ArrayList<>();
for (OrderEntry normal : normalEntries) {
    sortedList.add(normal);
    // 添加关联的赠品(去重)
    List<OrderEntry> relatedGifts = giftMap.getOrDefault(normal.getEntryNumber(), Collections.emptyList());
    for (OrderEntry gift : relatedGifts) {
        if (!addedGifts.contains(gift)) {
            sortedList.add(gift);
            addedGifts.add(gift);
        }
    }
}

// 验证输出
System.out.println(JSON.toJSONString(sortedList));

逻辑说明

  • 对于关联多个普通条目的赠品(如示例中关联1和2的赠品),通过addedGifts集合确保只在最后一个关联的普通条目后添加一次,完全匹配预期输出。
  • 整个过程未使用Comparator的compare静态方法和thenComparing链式调用,符合需求限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 23:05:57