java Comparator 排序和二次排序

说明

java.util.Comparator 类似 Comparable ,可以实现 排序 功能

应用场景

  • 某个类 不实现 Comparable 接口,又要进行比较

  • 某个类 实现了 Comparable 接口,但是开发者认为其比较方式并不是自己想要,需要 临时 改用自己的排序规则。
    如:List,其元素是 Integer 型,默认 从小到大排序,但要改成 从大到小排序

方法

Comparator接口里面有一个 compare 方法,如下:

int compare(T o1, T o2);

形参: 方法有两个参数 T o1T o2,是 泛型 的表示方式,分别表示待比较的两个对象。

注意:在集合中(如:数组、List),o1 表示 后一个元素o2 表示 前一个元素,如下图:

返回值:方法返回值是int,有三种情况:

  • 正整数
  • 负整数,此时交换这2个元素的位置
  • 0,表示 o1等于o2

返回值表示 排序规则

排序规则-正序(从小到大)

  • o1(后一个元素)大于 o2(前一个元素),返回 正整数
  • o1(后一个元素)小于 o2(前一个元素),返回 负整数会交换这2个元素的位置

排序规则-倒序(从大到小)

  • o2(前一个元素)大于 o1(后一个元素),返回 正整数
  • o2(前一个元素)小于 o1(后一个元素),返回 负整数会交换这2个元素的位置

例子-int 数组

从小到大排序,即:正序

这里只是为了演示,其实对于 int 型数组,不需要实现 Comparator,因为数字型本身就可以排序

package test;

import java.util.*;

public class Std_Comparator_array {

    public static void main(String[] args) {

        Integer[] array=new Integer[]{1,3,2};
        Arrays.sort(array,new MyComparator());
        System.out.println(Arrays.toString(array));
    }

    static class MyComparator implements Comparator<Integer> {
        /**
         *
         * @param o1 后一个元素
         * @param o2 前一个元素
         * @return 
         */
        @Override
        public int compare(Integer o1, Integer o2) {
            int ret=0;
            if(o2 > o1){
                ret=-1;
            }else if(o2 < o1){
                ret=1;
            }else{//等于
                ret=0;
            }
            return ret;
        }
    }
}

例子-int List

对于 int 型List,已经实现了 从小到大排序,但我们要改成 从大到小排序,即:倒序

package test;

import org.apache.flink.api.java.tuple.Tuple2;

import java.util.*;

public class Std_Comparator_list_daoxu {

    public static void main(String[] args) {
        List<Integer> list=new ArrayList();
        list.add(1);
        list.add(3);
        list.add(2);

        list.sort(new MyComparator()); // list本身排序
//        Collections.sort(list,new MyComparator()); //Collections.sort()排序
        System.out.println(Arrays.toString(list.toArray()));

    }

    static class MyComparator implements Comparator<Integer> {
        /**
         *
         * @param o1 后一个元素
         * @param o2 前一个元素
         * @return o1大于o2,返回正整数;o1小于o2,返回负整数;返回0,表示等于
         */
        @Override
        public int compare(Integer o1, Integer o2) {
            int ret=0;
            if(o2 < o1){
                ret=-1;
            }else if(o2 > o1){
                ret=1;
            }else{//等于
                ret=0;
            }
            return ret;
        }
    }
}

例子:对象类型

假设某类没有实现 Comparable 接口,但是又想进行比较
或者 实现了 Comparable 接口,但是开发者认为其比较方式并不是自己想要,需要 临时 改用自己的排序规则

根据年龄比较

Student 类,没有实现 Comparable 接口,但又想根据 年龄 进行比较

Student类:

package test;

public class Student {
    private String name;
    private int age;
    private int length;
    public Student(String name, int age,int length) {
        this.name = name;
        this.age = age;
        this.length = length;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public int getLength() {
        return length;
    }
    public void setLength(int length) {
        this.length = length;
    }
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return name+","+age+","+length;
    }
}

主类

package test;

import java.util.*;

public class Std_Comparator_list_Student {

    public static void main(String[] args) {
        Student std=new Student("李雷",20,182);
        Student std2=new Student("lucy",16,168);
        Student std3=new Student("lucy",16,167);
        Student std4=new Student("韩梅梅",25,165);
        Student std5=new Student("张三",16,185);

        List<Student> list=new ArrayList();
        list.add(std);
        list.add(std2);
        list.add(std3);
        list.add(std4);
        list.add(std5);

//        list.sort(new MyComparator()); // list本身排序
        Collections.sort(list,new MyComparator()); //Collections.sort()排序
        System.out.println(Arrays.toString(list.toArray()));

    }

    static class MyComparator implements Comparator<Student> {
        /**
         *
         * @param o1 后一个元素
         * @param o2 前一个元素
         * @return 
         */
        @Override
        public int compare(Student o1,Student o2) {
            int res=0;
            if( o1.getAge() < o2.getAge()){
                res=-1;
            }else if(o1.getAge() > o2.getAge()){
                res=1;
            }else{//相等
                res=0;
            }
            return res;
        }
    }
}

二次排序

对于上面的例子,当 年龄 相同时,身高从大到小排序

修改测试类,进行二次排序

package test;

import java.util.*;

public class Std_Comparator_list_Student2 {

    public static void main(String[] args) {
        Student std=new Student("李雷",20,182);
        Student std2=new Student("lucy",16,168);
        Student std3=new Student("lucy",16,167);
        Student std4=new Student("韩梅梅",25,165);
        Student std5=new Student("张三",16,185);

        List<Student> list=new ArrayList();
        list.add(std);
        list.add(std2);
        list.add(std3);
        list.add(std4);
        list.add(std5);

//        list.sort(new MyComparator()); // list本身排序
        Collections.sort(list,new MyComparator()); //Collections.sort()排序
        System.out.println(Arrays.toString(list.toArray()));

    }

    static class MyComparator implements Comparator<Student> {
        /**
         *
         * @param o1 后一个元素
         * @param o2 前一个元素
         * @return 
         */
        @Override
        public int compare(Student o1,Student o2) {
            int res=0;
            if( o1.getAge() < o2.getAge()){
                res=-1;
            }else if(o1.getAge() > o2.getAge()){
                res=1;
            }else{//相等
                //            res=0;
                //二次排序
                if(o1.getLength()>o2.getLength()){
                    res=-1;
                }else if(o1.getLength() < o2.getLength()){
                    res=1;
                }else{
                    res=0;
                }
            }
            return res;
        }
    }
}

原文出处:http://malaoshi.top/show_1IX2TE5dbYvz.html