首页 > 解决方案 > 按表示项目位置的可空字段排序

问题描述

我需要以自定义方式对我的对象数组进行排序。假设我的对象中有两个字段—— priority(可为空)和createdAt(不可为空)。优先级字段说明项目应该在哪个位置。但是,它可以为空。在这种情况下,我们应该考虑 createdAt 字段(按降序排列)进行排序。

让我用例子来解释一下。例如我的对象是:

Object0: priority: null, createdAt: 2018-12-01
Object1: priority: 1,    createdAt: 2018-12-02
Object2: priority: 5,    createdAt: 2018-12-03
Object3: priority: null, createdAt: 2018-12-04
Object4: priority: null, createdAt: 2018-12-05
Object5: priority: 2,    createdAt: 2018-12-06
Object6: priority: null, createdAt: 2018-12-07

最终顺序应该是:

  1. Object1(按其优先级)
  2. Object5(按其优先级)
  3. Object6(通过 createdAt desc 填充左侧位置)
  4. Object4(通过 createdAt desc 填充左侧位置)
  5. Object2(按其优先级)
  6. Object3(通过 createdAt desc 填充左侧位置)
  7. Object0(通过 createdAt desc 填充左侧位置)

我怎样才能实现我的目标?是否有任何开箱即用的比较器准备好?

编辑: 我认为我们可以使用该类:

public class MyObject {
   Integer priority;
   LocalDateTime createdAt;
}

标签: javaspringjava-streamcomparatorcomparable

解决方案


不,不要为此使用比较器,或者更准确地说,不要为整个工作使用比较器。比较器的工作是比较两个对象并判断这两个对象之间的顺序。它不适用于检测优先级序列中的间隙。

相反,假设优先级是完整且唯一的,我建议您对具有定义优先级的对象使用数组和一种基数排序。优先级 1 进入数组索引 1,优先级 2 索引 2 等。具有null优先级的对象在创建日期降序时使用比较器进行排序,然后填充到仍然存在的数组索引中null(我猜索引 0 除外)。

通过“假设优先级是完整且唯一的”,我的意思是您不会冒两个优先级为 3 的对象或优先级为 2.44 的对象的风险。

我可能会使用流并将Collectors.partitioningBy具有优先级的对象与没有优先级的对象分开,但当然还有其他方法可以做。

我会手动编码这个。我从未听说过任何现成的解决方案。搜索永远不会有害,但我会惊讶地找到一个。另一方面,不需要那么多代码行。

BTWLocalDate用于您的日期,因为他们没有一天中的时间(不是LocalDateTime)。


推荐阅读