【问题标题】:Collections sort(List<T>,Comparator<? super T>) method example [duplicate]集合 sort(List<T>,Comparator<? super T>) 方法示例
【发布时间】:2013-01-04 09:11:39
【问题描述】:

可能重复:
Sorting Java objects using multiple keys

我找不到任何使用此方法的示例,所有示例都给出了第二个参数“null”。 我听说这种方法用于根据多个标准对类进行排序,但没有找到示例。

public class Student implements Comparable<Student> {
String name;
int age;

public Student(String name, int age) {
    this.name = name;
    this.age = age;
}

@Override
public String toString() {
    return name + ":" + age;
}

@Override
public int compareTo(Student o) {
    Integer myAge = age;
    Integer oAge = o.age;
    return myAge.compareTo(oAge);
}

}

对于此类,如果我想根据学生的姓名和年龄对学生列表进行排序,我该如何使用 Collections sort(List,Comparator) 方法

【问题讨论】:

    标签: java


    【解决方案1】:

    在您现有的 Student 类的基础上,这是我通常的做法,尤其是当我需要多个比较器时。

    public class Student implements Comparable<Student> {
    
        String name;
        int age;
    
        public Student(String name, int age) {
           this.name = name;
           this.age = age;
        }
    
        @Override
        public String toString() {
            return name + ":" + age;
        }
    
        @Override
        public int compareTo(Student o) {
            return Comparators.NAME.compare(this, o);
        }
    
    
        public static class Comparators {
    
            public static Comparator<Student> NAME = new Comparator<Student>() {
                @Override
                public int compare(Student o1, Student o2) {
                    return o1.name.compareTo(o2.name);
                }
            };
            public static Comparator<Student> AGE = new Comparator<Student>() {
                @Override
                public int compare(Student o1, Student o2) {
                    return o1.age - o2.age;
                }
            };
            public static Comparator<Student> NAMEANDAGE = new Comparator<Student>() {
                @Override
                public int compare(Student o1, Student o2) {
                    int i = o1.name.compareTo(o2.name);
                    if (i == 0) {
                        i = o1.age - o2.age;
                    }
                    return i;
                }
            };
        }
    }
    

    用法:

    List<Student> studentList = new LinkedList<>();
    Collections.sort(studentList, Student.Comparators.AGE);
    

    编辑

    自 Java 8 发布以来,内部类 Comparators 可以使用 lambda 大大简化。 Java 8 还为Comparator 对象thenComparing 引入了一种新方法,在嵌套它们时无需手动检查每个比较器。下面是考虑了这些更改的 Student.Comparators 类的 Java 8 实现。

    public static class Comparators {
        public static final Comparator<Student> NAME = (Student o1, Student o2) -> o1.name.compareTo(o2.name);
        public static final Comparator<Student> AGE = (Student o1, Student o2) -> Integer.compare(o1.age, o2.age);
        public static final Comparator<Student> NAMEANDAGE = (Student o1, Student o2) -> NAME.thenComparing(AGE).compare(o1, o2);
    }
    

    【讨论】:

    • 感谢,JAVA 8 的创新功能确实让一些复杂的代码变得简单!
    【解决方案2】:

    这可能是最简单的方法 -

    Collections.sort(listOfStudent,new Comparator<Student>(){
                         public int compare(Student s1,Student s2){
                               // Write your logic here.
                         }});
    

    使用 Java 8(lambda 表达式)-

    listOfStudent.sort((s1, s2) -> s1.age - s2.age); 
    

    【讨论】:

    • 用 Apache 的 CompareToBuilder 之类的预构建解决方案替代这个逻辑不是更好吗?
    • @IgorGanapolsky 是也不是。当你的逻辑很简单时,它会是的。当你的比较逻辑很复杂时,它不是。 :)
    • s1.age - s2.age 的原因是什么?
    • @mbj s1.age - s2.age 翻译为按年龄值按升序对元素进行排序。
    【解决方案3】:

    你可能想要这样的东西:

    Collections.sort(students, new Comparator<Student>() {
                         public int compare(Student s1, Student s2) {
                               if(s1.getName() != null && s2.getName() != null && s1.getName().comareTo(s1.getName()) != 0) {
                                   return s1.getName().compareTo(s2.getName());
                               } else {
                                 return s1.getAge().compareTo(s2.getAge());
                              }
                          }
    );
    

    这会首先按学生的姓名对学生进行排序。如果缺少姓名,或者两个学生的姓名相同,则按年龄排序。

    【讨论】:

    • 如果只有一个名称为空,似乎不稳定。
    【解决方案4】:

    要使用 Collections sort(List,Comparator) ,您需要创建一个实现 Comparator 接口的类,以及其中的 compare() 代码,通过Comparator Interface

    你可以这样做:

    class StudentComparator implements Comparator
    {
        public int compare (Student s1 Student s2)
        {
            // code to compare 2 students
        }
    }
    

    要排序:

     Collections.sort(List,new StudentComparator())
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-07
      • 1970-01-01
      • 2011-04-17
      • 1970-01-01
      相关资源
      最近更新 更多