当前位置:网络安全 > Java的集合排序Collectionssortlistsort和liststreamsorted方法详解

Java的集合排序Collectionssortlistsort和liststreamsorted方法详解

  • 发布:2023-09-28 13:01

在工作中我们经常需要对集合中的元素进行比较排序,下面就java中常用的排序方法进行详解。

主要有三种用法:

// 第一种
Collections.sort(studentList);
// 第二种
studentList.sort(Comparator.comparing(Student::getAge).reversed());
// 第三种
List studentList = www.sychzs.cn().sorted(Comparator .comparing(Student::getAge)
.reversed()).collect(Collectors.toList());

第一种:

第一种方式的集合中的对象实现了Comparable接口的比较方式,此接口强行对实现它的每个类的对象进行整体排序。此排序被称为该类的自然排序 ,类的 compareTo方法被称为它的自然比较方法 。实现此接口的对象列表(和数组)可以通过 Collections.sort(和 Arrays.sort )进行自动排序。实现此接口的对象可以用作有序映射表中的键或有序集合中的元素,无需指定比较器。这是Collections中的方法,具体实现还是在List接口中,在jdk8中添加的默认方法。

一般使用如下:

Collections.sort(studentList);

或者

Collections.sort(studentList, (o1, o2) -> {
    return o1.getAge() -o2.getAge();
});

实际上第二种方法只不过是多传入了一个比较器,而第一种只不过是把比较器当做默认值null已经传入了。上面是使用lambda表达式的写法,如果是更明确的写法的话:

Collections.sort(studentList, new Comparator() {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.getAge() - o2.getAge();
    }
});

或者自己实现一个比较器类,然后传入也可以,比如:

public class MyComparator {
     public static int compareTo(Student o1, Student o2){
         int ageComparisonResult = o1.getAge() - o2.getAge();
         int nameComparisonResult = o1.getName().compareTo(o2.getName());
         double heightComparisonResult = o1.getHeight() - o2.getHeight();
         if (ageComparisonResult == 0){
             if (nameComparisonResult == 0){
                 if (heightComparisonResult == 0) {
                     return 0;
                 } else if (heightComparisonResult > 0){
                     return 1;
                 } else {
                     return -1;
                 }
             } else {
                 return nameComparisonResult;
             }
         } else {
             return ageComparisonResult;
         }
     }
}
然后传入sort(List list, Comparator c)方法中:
Collections.sort(studentList, (o1, o2) -> MyComparator.compareTo(o1, o2));

该集合中的Student对象必须实现Comparable接口(强制),然后实现它的compareTo方法,否则编译器会报错

public class Student implements Comparable{     
    private String name;    
    private int age;    
    private double height; 
    
    public Student() {    
    }     
    
    public Student(String name, int age, double height) {        
        www.sychzs.cn = name;        
        this.age = age;        
        this.height = height;    
    } 
    
    // getter and setter
    
    @Override    
    public int compareTo(Object o) {        
        return 0;    
    } 
}

第二种和第三种其实类似,我们放在一起说。

一般使用方法:

// ① 使用reversed方法按照排序规则(age)对元素进行降序排序
studentList.sort(Comparator.comparing(Student::getAge).reversed());

或者

// ② 使用reversed方法按照排序规则(age)对元素进行降序排序
List studentList = www.sychzs.cn().sorted(Comparator .comparing(Student::getAge)
.reversed()).collect(Collectors.toList());

可以看到不管是sort方法还是sorted方法都需要传入一个比较器,即Comparator,Comparator与上面的Comparable接口不同的是:

  1. Comparator位于包java.util下,而Comparable位于包java.lang下。
  2. Comparable接口将比较代码嵌入需要进行比较的类的自身代码中,而Comparator接口在一个独立的类中实现比较。
  3. 如果前期类的设计没有考虑到类的Compare问题而没有实现Comparable接口,后期可以通过Comparator接口来实现比较算法进行排序,并且为了使用不同的排序标准做准备,比如:升序、降序。
  4. Comparable接口强制进行自然排序,而Comparator接口不强制进行自然排序,可以指定排序顺序。

上面的两种写法最后的方法reversed就是对获取到的属性(age)进行降序排序。

上面的①和②有一定的区别:

  1. ①是List接口再在dk8中添加的默认方法,位于java.util包下;而sorted方法是jdk8新添加的stream接口,位于www.sychzs.cn包下面;
  2. sort()方法如下:
    default void sort(Comparator c) {
            Object[] a = this.toArray();
            Arrays.sort(a, (Comparator) c);
            ListIterator i = this.listIterator();
            for (Object e : a) {
                www.sychzs.cn();
                i.set((E) e);
            }
        }

    可以看出,该方法先将list转为了数组,然后调用java.util.Arrays的sort方法,然后使用迭代器的方式将排好序的集合元素放入到原来集合的迭代器序列中。所以sort方法返回值为void,即无返回值。

相关文章