按多个属性对对象排序

时间:2016-09-19 11:10:12

标签: java

我一直在做一些事情,要求我按三个属性 - name (str)colour (str)volume (int)对物品(软饮料)进行分类。我已经研究过,并找到了通过名称,颜色和体积分别订购它们的方法,但有没有办法在三个方面对它们进行订购?

我的意思是:例如,假设有四个SoftDrink对象:Fanta Orange 500,Coke Red 500,Coke Silver 500 Fanta Orange 400.

我正在寻找的输出是:

  
      
  • 1)Coke Red 500
  •   
  • 2)可乐银500
  •   
  • 3)芬达橙400
  •   
  • 4)芬达橙500
  •   

首先按名称排序,然后按颜色排序,然后按体积排序(升序)。

我目前正在使用三个比较器:nameComparatorcolourComparatorvolumeComparator,但每个比较器仅按名称对对象进行排序,然后仅按颜色排序,然后按体积排序。是否可以使用Comparator根据多个属性进行排序?

2 个答案:

答案 0 :(得分:12)

尝试这样的事情:

drinks.sort(
      Comparator.comparing(Drink::getName).thenComparing(Drink::getColour).thenComparing(Drink::getVolume)
    );

请记住为您的属性设置getter(getNamegetColour等)。这就是您所需要的,无需任何自定义比较器或任何东西。

答案 1 :(得分:1)

亚历!

通过比较器回答关于通过多个属性对实体进行排序的问题,这里是关于对象排序的java教程的链接: https://docs.oracle.com/javase/tutorial/collections/interfaces/order.html

特别是有一个Comparator的例子,它首先按日期比较对象,然后(在相等的情况下)按数字比较它们:

static final Comparator<Employee> SENIORITY_ORDER = 
                                        new Comparator<Employee>() {
    public int compare(Employee e1, Employee e2) {
        int dateCmp = e2.hireDate().compareTo(e1.hireDate());
        if (dateCmp != 0)
            return dateCmp;

        return (e1.number() < e2.number() ? -1 :
               (e1.number() == e2.number() ? 0 : 1));
    }
};

将此模式应用于您的案例很容易:

static final Comparator<SoftDrink> DRINKS_ORDER = new Comparator<SoftDrink>() {
    public int compare(SoftDrink d1, SoftDrink d2) {
        int nameCmp = d1.getName().compareTo(d2.getName());
        if (nameCmp != 0) {
            return nameCmp;
        }
        int colorCmp = d1.getColor().compareTo(d2.getColor());
        if (colorCmp != 0) {
            return colorCmp;
        }
        return d1.getVolume() < d2.getVolume() ? -1 : (d1.getVolume() == d2.getVolume() ? 0 : 1);
    }
};

在调用compareTo方法之前,请务必检查空值(如有必要)。