简体   繁体   English

Java Collections.sort()比较器

[英]Java Collections.sort() Comparator

I am sorting my custom objects. 我正在排序自定义对象。 Custom object contain state and timestamp. 自定义对象包含状态和时间戳。 First I have to sort against state then timestamp. 首先,我必须对状态进行排序,然后对时间戳进行排序。 State having below values 低于数值的状态

Running, Waiting, Registering, Completed and Aborted 运行,等待,注册,完成和中止

So state having value Running should come on top then Waiting and so on. 因此,具有运行价值的状态应该放在最上面,然后是等待状态,依此类推。

If I have to sort alphabetically then I can do easily via 如果我必须按字母顺序排序,那么我可以轻松地通过

state1.compareTo(state2)

But can I sort with this criteria. 但是我可以按照这个标准进行排序吗? Please help me to write this logic. 请帮我写这个逻辑。

EDIT 编辑

As you people suggested I took Enum 正如你们所建议的,我服用了Enum

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

And compare like below 并比较如下

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

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

Thank you very much for your support. 非常感谢您的支持。

You can use composition of comparator functions: 您可以使用比较器功能的组成:

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

The last line may need to be changed accordingly, depending on the data type: 最后一行可能需要相应地更改,具体取决于数据类型:

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

Or even 甚至

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

Comparator.thenComparing is documented with this comment: Comparator.thenComparing带有以下注释:

Returns a lexicographic-order comparator with another comparator. 返回带有另一个比较器的字典顺序比较器。 If this Comparator considers two elements equal, ie compare(a, b) == 0, other is used to determine the order. 如果此比较器认为两个元素相等,即compare(a,b)== 0,则使用其他元素确定顺序。

Note that MyClass.state is assumed to be comparable in this case, such as being an enum, which is inherently comparable. 请注意,在这种情况下,假定MyClass.state是可比较的,例如作为枚举,其本质上是可比较的。 If it's plain strings, then you may need custom logic there too, such as with: 如果是纯字符串,那么您可能也需要自定义逻辑,例如:

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

You can create a custom comparator for your State class, like this : 您可以为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);
    }

}

You can create an enum like 您可以创建一个枚举

public enum State {
    RUNNING, WAITING, REGISTERING, COMPLETED, ABORTED
}

By default, these states will get an ordinal integer which will be according to the order you write them in the enum. 默认情况下,这些状态将获得一个序数整数,该整数将与您在枚举中写入它们的顺序一致。 And then use this State as your state in your object and the create comparator 然后用这个State为您的state在对象和创建比较

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

And then you can use the comparator to sort your collections 然后可以使用比较器对集合进行排序

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM