对多个Comparator项目排序表

时间:2016-06-16 07:50:34

标签: sorting lambda java-8 comparator

我需要在Java 8中使用多个Comparator对象对Item对象列表进行排序。

应用程序为每个用户操作创建一个Comparator。它将Comparator对象存储在ArrayList中。可以对一个比较器项进行排序,但现在我们需要一种方法来同时对多个Comarator项进行排序。

我用这行代码对列表进行排序:

tbl.getItems().stream().sorted(groupingComparator);

变量groupingComparator来自类型Comparator<Item>

现在我需要对存储在

中的多个字段进行排序
ArrayList<Comparator<Item>>

这在Java 8中是否可行?我该如何实现呢?

2 个答案:

答案 0 :(得分:5)

您可以使用Comparator接口提供的thenComparing(Comparator)方法将多个Comparators链接在一起。请参阅下面的示例,使用流从List创建这样的链式比较器。

我们要用于排序的域类:

public static class Order {
    String customer;
    String item;

    public Order(String customer, String item)
    {
        this.customer = customer;
        this.item = item;
    }

    public String toString() {
        return "Customer: " + customer + " Item: " + item;
    }
}

示例代码:

public static void main(String... args) throws Throwable
{
    List<Order> orders = new ArrayList<>();
    orders.add(new Order("A", "Item 1"));
    orders.add(new Order("B", "Item 3"));
    orders.add(new Order("A", "Item 2"));
    orders.add(new Order("B", "Item 1"));

    List<Comparator<Order>> comparators =
        Arrays.asList((o1, o2) -> o1.customer.compareTo(o2.customer), // comparator for customer names
                      (o1, o2) -> o1.item.compareTo(o2.item));        // comparator for item names

    Comparator<Order> comp =
        comparators.stream()
                   .reduce(Comparator::thenComparing)
                   // use a default comparator if the comparator list was empty
                   .orElse(Comparator.comparing(Object::toString));

    orders.stream().sorted(comp).forEach((order) ->  System.out.println(order));
}

此代码段将打印首先由客户排序的订单,然后按项目名称排序。

答案 1 :(得分:2)

就这么简单:

public class CompositeComparator implements Comparator<Item> {
    private List<Comparator<Item>> comparators;

    public CompositeComparator(List<Comparator<Item>> comparators) {
        this.comparators = comparators;
    }

    @Override
    public int compare(Item o1, Item o2) {
        int result = 0;
        for (Comparator<Item> c : comparators) {
            result = c.compare(o1, o2);
            if (result != 0) {
                break;
            }
        }
        return result;
    }
}