Skip to content

需求背景

在已知可用(满减、折扣)红包集合的情况下,需要按照多个规则进行排序;

  1. 实际减免金额从大到下排序;
  2. 上述规则相同,卖家分摊比例从大到小排序;
  3. 上述规则相同,满减类型红包优先;
  4. (上述规则相同,按原条件排序)

JDK 8 的次级排序

别再写那种 if 嵌套 if 的恶心代码。

java
// 先计算每个红包实际减免金额
Map<Long, Integer> reduceMap = redList.stream().collect(Collectors.toMap(Coupon::getId, item -> getReducePrice(item, nowPrice)));
// 一级排序:实际减免金额
Comparator<Coupon> comparator1 = Comparator.comparingInt(k -> reduceMap.get(k.getId()));
// 二级排序:卖家分摊比例
Comparator<Coupon> comparator2 = Comparator.comparingInt(k -> k.getSettle().getSeller());
// 三级排序:满减类型红包优先
Comparator<Coupon> comparator3 = (k1, k2) -> {
    return k1.isFullReduce() ? -1 : (k2.isFullReduce() ? 1 : 0);
};
redList.sort(
        // 从大到小
        comparator1.reversed()
                // 从大到小
                .thenComparing(comparator2.reversed())
                .thenComparing(comparator3)
);

java.util.Comparator#compare

很多人不清楚 int compare(T o1, To2) 返回值怎么影响排序的,总结两点;

  1. 只有三种结果,"< 0"、"== 0" 和 "> 0";
  2. "< 0" 则 o1 在前,o2 在后;
  3. "== 0" 则按原顺序不变;
  4. "> 0" 则 o2 在前,o1 在后;

JDK 大部分的包装类都实现了 Comparator 接口,例如 Integer、Long 和 String 等等。而且像 Integer 和 Long 这种额外新增了 public static int compare(int x, int y) 静态方法,在 Lambda 下显得更优雅。

例如按照学生年龄排序:studentList.sort(Comparator.comparingInt(Student::getAge))

基于 MIT 许可发布