Collections集合工具类排序


数组有工具类Arrays,集合也有一个工具类Collections,这里练习一下集合工具类的排序方法,顺便过一下sort排序方法,比较器。

sort方法

  • sort(List<T> list):根据其元素的natural ordering对指定的列表进行排序。
  • sort(List<T> list, Comparator<? super T> c):根据指定的比较器引起的顺序对指定的列表进行排序。

第一个方法使用:

public class Dome01 {
    public static void main(String[] args) {
        ArrayList<Integer> arrayList = new ArrayList<Integer>();
        //Collections集合工具的添加方法
        Collections.addAll(arrayList, 21,31,23,12,54,-21,3,98,0);

        arrayList.forEach((s) -> System.out.print(s+"  "));//依次输出并没有排序 21  31  23  12  54  -21  3  98  0  
        //调用sort方法排序
        Collections.sort(arrayList);
        arrayList.forEach((s) -> System.out.print(s+"  "));//从小到大排序输出 -21  0  3  12  21  23  31  54  98  

    }
}

上面是针对int 数据类型的数据排序,在针对其他类型的数据时,使用sort排序就不会生效,如下:

public static void main(String[] args) {
        ArrayList<Character> arrayList = new ArrayList<Character>();
        Collections.addAll(arrayList, 'w','s','o','q');
        arrayList.forEach((s) -> System.out.print(s)); // 依次打印 wsoq 并没有进行abc 做这样排序
    }

这个时候,就要使用第二种方式了比较器实现

public static void main(String[] args) {
        ArrayList<Character> arrayList = new ArrayList<Character>();
        Collections.addAll(arrayList, 'f','s','q','h','1');
        Collections.sort(arrayList, new Comparator<Character>() {
            @Override
            public int compare(Character o1, Character o2) {
                return o1 - o2;
            }
        });
        arrayList.forEach(s -> System.out.print(s+"  "));//根据ASCII排序 1  f  h  q  s  
    }

o1 - o2是从小到大排序,反过来就少从大到小,上面使用匿名内部类使用的。

排序自定义类型:

public class ComparatorDome {
    public static void main(String[] args) {
        Student[] student = new Student[5]; // 实例化Student并定义为数组
        // 赋值 0 1 2 3 4 5
        student[0] = new Student("zhangsan", 16);
        student[1] = new Student("lisi", 22);
        student[2] = new Student("wangwu", 19);
        student[3] = new Student("tom", 27);
        student[4] = new Student("tom", 17);

        int a[] = { 32, 31, 2, 334, -212, 99 };
        Arrays.sort(a); // Arrays.sort Arrays工具类提供方法排列数组
        System.out.println(Arrays.toString(a));
        /* Arrays工具类可以拍类基本数据类型的数组 但是怎么排列上面的学生类数据呢 */

        /* 比较器的使用 */
        // 第一种使用手动排序方法Comparator接口
        Arrays.sort(student, new ComparatorDome02());
        System.out.println(Arrays.toString(student));
        // 第二种使用自然排序方法 Comparable接口
        Arrays.sort(student);
        System.out.println(Arrays.toString(student));
    }
}

/*
 * 由于接口无法实例化对象,所以我们,创建一个类来实现它 然后来创建这个类的对象
 */
class ComparatorDome02 implements Comparator<Student> { // Comparator是用来手动排序的类 Comparable是默认自然比较器

    // 重写compareTo方法
    @Override
    public int compare(Student o1, Student o2) {
        if (o1.getAge() - o2.getAge() == 0) {
            return o1.getName().charAt(0) - o2.getName().charAt(0);
        } else {
            return o1.getAge() - o2.getAge();
        }
    }
    /*
     * 总结比较器: 在对Student排序的时候,由于在Arrays
     * 工具类中没有定义Student类型的排序规则,jvm编译时在想我该怎么编译这个玩意呢,当然jvm毕竟是 机器它不会去思考,所以jvm直接反馈一个错误给我们
     * java.lang.ClassCastException,所以可以想到jvm排序这个Student需要一个规则,一个叫jvm怎么去排序这个数组的规则。通过解刨源码
     * 我们可以发现,在排序基本类型数据时,源码都继承了一个接口 Comparable<Integer>再次跟进  发现定义规则的抽象方法compareTo 
     * 照葫芦画瓢,我们定义规则并将规则传达给Arrays工具类,使其按照我们定义的规则来排序数组
     * Comparable,Comparator两个比较器达到的目的都是一样的,但是实现方法两种:一个是在该Student类中直接定义  ,一个是假借他人之手
     * 来制定规则,         排序的依旧是Arrays工具类,我们做的是制定规则
     */
}

Comparable和Comparator两个接口的区别

Comparable :强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的compareTo方法被称为它的自然比较方法。只能在类中实现compareTo()一次,不能经常修改类的代码实现自己想要的排序。实现此接口的对象列表(和数组)可以通过Collections.sort(和Arrays.sort)进行自动排序,对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。

Comparator: 强行对某个对象进行整体排序。可以将Comparator 传递给sort方法(如Collections.sort或Arrays.sort),从而允许在排序顺序上实现精确控制。还可以使用Comparator来控制某些数据结构(如有序set或有序映射)的顺序,或者为那些没有自然顺序的对象collection提供排序。


原文链接:https://www.cnblogs.com/2979100039-qq-con/p/13514036.html