【问题标题】:Using enum to sort a list使用枚举对列表进行排序
【发布时间】:2012-08-02 21:25:56
【问题描述】:

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

https://stackoverflow.com/a/1421537/1549672

我对 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;
        }
    };
}

有人可以解释一下它是如何工作的……它到底是做什么的? 谢谢!

【问题讨论】:

  • 我会单步调试您的调试器中的代码。这将允许您查看每一行的作用。
  • 在这种情况下实际上可能有点困难,因为代码执行相对复杂。除非您编写自己的代码来执行它,否则“比较”甚至可能不会被执行。
  • 看看docs.oracle.com/javase/6/docs/api/java/lang/Enum.html#ordinal()我想这就是你要找的。​​span>
  • 这段代码是否有一些你不理解的特定部分?

标签: java sorting


【解决方案1】:

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

实际上它将创建一个新的 Comparator 来执行此操作,方法是创建一个基于 Comparator 接口的匿名类。

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"
        }
    };
}

【讨论】:

  • 谢谢!这对于理解发生了什么非常有帮助!
【解决方案2】:

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

  • PersonComparator.ID_SORT 将通过 id (0 比较 Person 对象
  • PersonComparator.NAME_SORT 将使用自然(字典)顺序(“a”

如果您的 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) 

它会首先按他们的ids 对人进行排序,如果 id 相同,那么它将按他们的名字对他们进行排序

(1,"Jack") (2,"Adam") (2,"Jack")

也是由

创建的比较器
getComparator(PersonComparator.NAME_SORT, PersonComparator.ID_SORT) 

将首先比较名称,并且仅当名称相同时才会比较 Person 的 id,因此您将以这种方式对人员进行排序

(2,"Adam") (1,"Jack") (2,"Jack")

【讨论】:

  • 谢谢!这实际上正是我想要的!只是为了澄清一下,当您运行 getComparator 时,是否可以只使用 1 个字段? (例如 getComparator(PersonComparator.NAME_SORT) )?
  • 很高兴我能帮上忙。也想描述代码,但 Markus Mikkolainen 在他的回答中做得很好:)
【解决方案3】:

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

比较它的两个参数的顺序。返回一个负整数, 零或正整数,因为第一个参数小于、等于 到,或大于秒

【讨论】:

    【解决方案4】:

    基本上,此方法接收可变数量的 PersonComparator 对象,然后遍历它们以比较两个人员对象,返回第一个比较器,该比较器不返回两个给定人员对象之间的匹配项。

    【讨论】:

      【解决方案5】:

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

      您的比较器在 for 循环中使用此 PersonComparators,如果由于当前 PersonComparator 而导致人员不相等,则返回结果。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-09
        • 1970-01-01
        • 2021-05-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多