首页 > 解决方案 > Java Collections.sort() 比较器

问题描述

我正在对我的自定义对象进行排序。自定义对象包含状态和时间戳。首先,我必须对状态进行排序,然后是时间戳。具有以下值的状态

运行、等待、注册、完成和中止

因此,具有价值 Running 的状态应该排在首位,然后是 Waiting 等等。

如果我必须按字母顺序排序,那么我可以通过

state1.compareTo(state2)

但是我可以用这个标准排序吗?请帮我写这个逻辑。

编辑

正如你们建议的那样,我采用了 Enum

private enum TournamentState {
    Running,
    Waiting,
    Registering,
    Completed,
    Aborted
}

并像下面这样比较

int sort = EnumState.valueOf(status1).compareTo(EnumState.valueOf(status2));

if(sort != 0){
  return sort;
}else{
   return (int) (time1 - time2);
}

非常感谢您的支持。

标签: javasorting

解决方案


您可以使用比较器功能的组合:

Comparator<MyClass> comparator = Comparator.comparing(MyClass::getState)
    .thenComparing(MyClass::getTimeStamp);

最后一行可能需要相应更改,具体取决于数据类型:

.thenComparingLong(MyClass::getTimeStamp); //if it's a long TS

甚至

.thenComparing((ts1, ts2) -> {
    //custom comparison logic for time stamp values
    return result;
 });

Comparator.thenComparing与此评论一起记录:

返回具有另一个比较器的字典顺序比较器。如果此 Comparator 认为两个元素相等,即 compare(a, b) == 0,则使用 other 来确定顺序。

请注意,MyClass.state在这种情况下假定它是可比较的,例如作为一个枚举,它本质上是可比较的。如果它是纯字符串,那么您可能也需要自定义逻辑,例如:

final String order = "Running, Waiting, Registering, Completed and Aborted";
Comparator<MyClass> comparator = 
  Comparator.comparingInt(e -> order.indexOf(e.getState()))
    .thenComparing(MyClass::getTimeStamp);

推荐阅读