根据未知数量的键对对象列表进行排序

时间:2018-08-14 14:52:38

标签: java java-8

如果您知道传入的密钥或至少传入的密钥数目,我已经看到了很多方法来对可以正常工作的对象列表进行排序。 我的问题是我不知道用户会发送1个还是10个密钥。

当前,我对每个键的数量都有一个巨大的switch语句,但是显然,它的伸缩性非常好。它只是将一堆“ thenComparing”链接在一起。

我在这里找到了一个看起来有点帮助的示例,但我不知道如何构建比较器流。

How-to chain and apply a stream of comparators?

正在寻找链接或几乎所有信息,这些信息将填补如何执行此操作的空白。

这一切都可以通过用户调用webservice的方式完成,

https://host.com/path?sort=[{"attribute1": "ASC"}, {"attribute2": "DESC"}]

2 个答案:

答案 0 :(得分:6)

假设您有这样一个实体:

static class Person {
    private final int age;

    private final String name;

    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }
}

您可以定义所有字段并将其映射到某个比较器:

Map<String, Comparator<Person>> map = new HashMap<>();
map.put("name_ASC", Comparator.comparing(Person::getName));
map.put("name_DESC", Comparator.comparing(Person::getName).reversed());

map.put("age_ASC", Comparator.comparingInt(Person::getAge));
map.put("age_DESC", Comparator.comparingInt(Person::getAge).reversed());

然后输入您的信息,您可以这样做:

Comparator<Person> all = Stream.of("name_ASC", "age_DESC") // for example
            .map(map::get)
            .reduce(Comparator::thenComparing)
            .orElse((a, b) -> 0); // or whatever you think appropriate

然后对它们进行排序显然是没有道理的:

 List<Person> persons = List.of(new Person(20, "Bob"), new Person(30, "Rose"));

 // or Collections.sort(persons, all)
 // persons.sort(all)
 persons.stream().sorted(all).collect(Collectors.toList());

答案 1 :(得分:1)

如果您可以建立一个比较器列表,则可以使用如下所示的内容:

public class MultiComparator<T> implements Comparator<T> {

    private final List<Comparator<T>> comparators;

    MultiComparator(List<Comparator<T>> comparators){
        this.comparators = comparators;
    }

    @Override
    public int compare(T t1, T t2) {
        int r = 0;
        for(Comparator c : comparators){
            r = c.compare(t1,t2);
            if(r != 0){
                return r;
            }
        }
        return r;
    }

}

(虽然不是Java 8版本)