使用枚举类型对列表进行排序

3

我在寻找一种根据对象的多个字段之一对列表进行排序的方法(最终只是自己提出问题),但在我的研究中,我遇到了这个答案:

https://dev59.com/_HM_5IYBdhLWcg3wUxjF#1421537

我对Java还不太熟悉,可能这就是原因,但我不太理解这个最后的方法:

public static Comparator<Person> getComparator(final PersonComparator... multipleOptions) {
    return new Comparator<Person>() {
        public int compare(Person o1, Person o2) {
            for (PersonComparator option : multipleOptions) {
                int result = option.compare(o1, o2);
                if (result != 0) {
                    return result;
                }
            }
            return 0;
        }
    };
}

请问能否解释一下它是如何工作的,以及它到底是做什么的吗? 谢谢!


1
我会在调试器中逐步执行你的代码。这样可以让你看到每行代码的作用。 - Peter Lawrey
在这种情况下,由于代码执行相对复杂,实际上可能会有点困难。而且,“compare”可能甚至不会被执行,除非您编写自己的代码来执行它。 - Markus Mikkolainen
请查看http://docs.oracle.com/javase/6/docs/api/java/lang/Enum.html#ordinal(),我认为这就是你要找的。 - SHiRKiT
你对这段代码有什么不理解的地方吗? - Code-Apprentice
5个回答

4

它将找到第一个不返回“equals”的比较器并返回其值,否则它将返回“equals”。

实际上,它将创建一个新的比较器来完成此操作,通过基于比较器接口创建一个匿名类。

public static Comparator<Person> getComparator(
   final PersonComparator... multipleOptions) 
{        
    return new Comparator<Person>() { //create anonymous class 
        public int compare(Person o1, Person o2) { //which implements the only method 
                                                   //in Comparator
            for (PersonComparator option : multipleOptions) { //loop through given 
                                                              //comparators
                int result = option.compare(o1, o2);
                if (result != 0) {                         //return value of the first
                    return result;                         //which says "non-equal"
                }
            }
            return 0;//all said "equals" so we say "equals"
        }
    };
}

谢谢!这对我理解正在发生的事情非常有帮助! - user1549672

1

getComparator方法将返回比较器,该比较器将根据其参数中传递的比较器来比较两个Person对象。每个PersonComparator都旨在通过Person类字段之一来比较Person,例如

  • PersonComparator.ID_SORT将按id(0 < 1 < 2 < 3 < ...)比较Person对象
  • PersonComparator.NAME_SORT将使用自然(字典)顺序按名称比较Person对象(“a”<“aa”<“ab”<“b”)。

如果您的Person类有更多字段,则可以将新比较器添加到枚举PersonComparator中。

此外,传递给getComparator方法的PersonComparators的顺序很重要。
例如,如果您有Persons

Person p1 = new Person(1,"Jack");
Person p2 = new Person(2,"Jack");
Person p3 = new Person(2,"Adam");

你将通过以下方式创建比较器

getComparator(PersonComparator.ID_SORT,PersonComparator.NAME_SORT) 

它将首先按照人员的id进行排序,如果id相等,则按照姓名进行排序。

(1,“杰克”)(2,“亚当”)(2,“杰克”)

同时创建比较器。

getComparator(PersonComparator.NAME_SORT, PersonComparator.ID_SORT) 

首先将比较人员的姓名,只有在姓名相等的情况下才会比较其ID,因此您将以此方式对人员进行排序

(2,“Adam”)(1,“Jack”)(2,“Jack”)


谢谢!这正是我在寻找的!只是想澄清一下,当你运行getComparator时,是否可能只使用一个字段?(例如:getComparator(PersonComparator.NAME_SORT))? - user1549672
1
很高兴能够帮忙。我也想描述一下代码,但Markus Mikkolainen在他的回答中已经做得非常好了 :) - Pshemo

1

您正在使用比较器比较两个人对象。

比较其两个参数的顺序。如果第一个参数小于、等于或大于第二个参数,则返回负整数、零或正整数


0

基本上,这个方法接收可变数量的PersonComparator对象,然后迭代它们来比较两个人物对象,并返回第一个不返回给定两个人物对象之间匹配的比较器。


0

你将其他比较器的列表 final PersonComparator... multipleOptions 传递给方法 getComparator

你的比较器在 for 循环中使用这些 PersonComparators,并且如果当前 PersonComparator 导致人员不相等,则返回结果。

因此,基本上,该方法返回一个 Comparator,如果所有传递的比较器都由于 Persons 相等而返回 0,或者从传递的比较器 compareTo 方法中返回第一个不匹配的 int。


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