Java Collections.sort()比较器

时间:2018-06-18 11:49:21

标签: java sorting

我正在整理自定义对象。自定义对象包含状态和时间戳。首先,我必须对状态然后时间戳进行排序。状态低于值

  

正在运行,等待,注册,完成和中止

因此,具有值运行的状态应该排在最前面,然后等待等等。

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

轻松完成
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);
}

非常感谢您的支持。

3 个答案:

答案 0 :(得分:4)

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

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

  

返回带有另一个比较器的字典顺序比较器。如果此比较器认为两个元素相等,即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);

答案 1 :(得分:2)

您可以为State类创建自定义比较器,如下所示:

public final class StateComparator implements Comparator<State>
{

    private int getRank(final State s)
    {
        if (s.getValue().equals("Running"))
        {
            return 1;
        } else if (s.getValue().equals("Waiting")) {
            return 2;
        } else if (s.getValue().equals("Registering")) {
            return 3;
        } else if (s.getValue().equals("Completed")) {
            return 4;
        } else if s.getValue().equals("Aborted") {
            return 5;
        } else {
            return Integer.MAX_VALUE;
        }

    }

    public int compare(final State s1, final State s3)
    {
        return getRank(s1) - getRank(S2);
    }

}

答案 2 :(得分:0)

您可以创建一个类似

的枚举
public enum State {
    RUNNING, WAITING, REGISTERING, COMPLETED, ABORTED
}

默认情况下,这些状态将获得一个序数整数,该整数将根据您在枚举中写入的顺序。然后在您的对象和创建比较器

中使用此State作为state
Comparator<MyClass> comparator = Comparator.comparing(MyClass::getState)
    .thenComparing(MyClass::getTimeStamp);

然后您可以使用比较器对集合进行排序