按多个属性对对象进行排序。

3

我正在做一些需要按照三个属性(名称(str)、颜色(str)和容量(int))对对象(软饮料)进行排序的事情。我已经进行了一些研究,找到了分别按名称、颜色和体积排序的方法,但是是否有一种方法可以按照这三个属性对它们进行排序?

我的意思是:例如,假设有四个软饮料对象:Fanta Orange 500、Coke Red 500、Coke Silver 500和Fanta Orange 400。

我要求的输出结果应该是:

  • 1) Coke Red 500
  • 2) Coke Silver 500
  • 3) Fanta Orange 400
  • 4) Fanta Orange 500

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

我目前正在使用三个比较器:nameComparator、colourComparator和volumeComparator,但每个比较器都只按名称、颜色和体积排序。是否有可能使用比较器根据多个属性进行排序?


提示:今年夏天有一个很好的演示:http://2016.java-forum-stuttgart.de/_data/D4_Wiedeking.pdf ...其中一些幻灯片上有德语文本,但主要是Java源代码示例。这个东西采用lambda来比较各种事物......达到了新的水平。 - GhostCat
@GhostCat 那个链接对我不起作用 :/ 它只是把我带到了主页。 - Jorn Vernee
带我去首页,但如果您有链接,请随意发布。非常有兴趣了解如何更详细地比较事物 :) - Paul12596
看起来可以。我会试一下。谢谢。 - Paul12596
2个回答

12

试着像这样做:

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

记得为您的属性设置getter方法(getName, getColour等)。这就是你需要的全部,不需要任何自定义比较器或其他任何东西。


3
最后一种类型是 int,因此您可以使用 thenComparingInt 来避免一些装箱操作。 - Jorn Vernee
运行得非常完美。谢谢! - Paul12596

1

Alex!

回答你有关使用比较器按多个属性排序实体的问题,这里是有关对象排序的Java教程链接: https://docs.oracle.com/javase/tutorial/collections/interfaces/order.html

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

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方法之前,请确保检查值是否为null(如果需要)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接