我一直在做一些事情,要求我按三个属性 - 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
首先按名称排序,然后按颜色排序,然后按体积排序(升序)。
我目前正在使用三个比较器:nameComparator
,colourComparator
和volumeComparator
,但每个比较器仅按名称对对象进行排序,然后仅按颜色排序,然后按体积排序。是否可以使用Comparator根据多个属性进行排序?
答案 0 :(得分:12)
尝试这样的事情:
drinks.sort(
Comparator.comparing(Drink::getName).thenComparing(Drink::getColour).thenComparing(Drink::getVolume)
);
请记住为您的属性设置getter(getName
,getColour
等)。这就是您所需要的,无需任何自定义比较器或任何东西。
答案 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方法之前,请务必检查空值(如有必要)。