ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java中Comparable<T>与Comparator<T>的使用——对数组中数据进行自定义排序

2021-10-10 21:05:38  阅读:167  来源: 互联网

标签:Comparable Java name 自定义 int Student2 age number o2


        Comparable<T>和Comparator<T>是Java中适用于不同情景下的用来对数据进行比较(排序)的两个接口。

下面举例展示Comparable接口的使用:

情景:有一个存放6个student的数组,每个student有age、name、number三个属性,要求按照number升序,age降序,name按字符串长度升序 的规则对数组中的student进行排序。

代码演示:

定义一个Student类,实现Comparable<T>接口,重写comparaTo方法,在方法中制定规则

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

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

    public Student() {
    }

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", number=" + number +
                ", name='" + name + '\'' +
                '}';
    }

    @Override
    /**
     * number升序
     * age降序
     * name按长度升序
     */
    public int compareTo(Student o) {
        int i = this.number - o.number;
        int j = this.age - o.age;
        int k = this.name.length()-o.name.length();
        return i != 0 ? i : (j != 0 ? -j : k);
    }
}

关于compareTo方法的使用规则:

this可以看成前面已经经过比较的数据,o可以看成后面新来的将要进行比较的数据。返回正数则表示o因该排在this前面,返回负数则表示o应该排在this后面,返回0则表示两个没有前后之分。若方法体中只写return一个正数,则这组数据排列顺序不变,如果只写return一个负数,则将原来的排列顺序进行反转。(例子中采用三目运算符进行逻辑判断,也可以采用if()语句)

下面定义测试类检验排序结果:

public class ComparableDemo {
    public static void main(String[] args) {
        //创建学生并放入数组
        Student[] stuArr = {
                new Student(18, 101, "张三"),
                new Student(18, 101, "张三子"),
                new Student(19, 101, "李四"),
                new Student(19, 102, "张四"),
                new Student(18, 103, "张十三"),
                new Student(17, 103, "王五")
        };
        //调用java.util.Arrays.sort方法
        java.util.Arrays.sort(stuArr);
        for (Student student : stuArr) {
            System.out.println(student);
        }
    }
}

运行结果:


 


下面举例展示Comparator接口的使用:

情景:有一个存放6个student的数组,每个student有age、name、number三个属性。

需求一:按照number、age、name依次升序排序

需求二:按照number、age、name依次降序排序

需求三:按照number升序,age降序,name按字典顺序排序

······

要求所有需求都在同一个测试类中实现。

代码演示:

·定义学生类:(该类只是一个普通的学生类,没有实现任何接口)

  • class Student2 {
        private int age;
        private int number;
        private String name;
    
        public Student2(int age, int number, String name) {
            this.age = age;
            this.number = number;
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public int getNumber() {
            return number;
        }
    
        public String getName() {
            return name;
        }
    
        public Student2() {
        }
    
        @Override
        public String toString() {
            return "Student2{" +
                    "age=" + age +
                    ", number=" + number +
                    ", name='" + name + '\'' +
                    '}';
        }
    }
·接下来定义比较器类,实现Comparator接口,重写compare方法。
ComparatorMachine01用来实现需求一;ComparatorMachine03用来实现需求三;需求二我们将比较器类写成内部类形式或Lambda表达式来实现。比较器类须实现Comparator<T>接口,T为比较对象的数据类型。
/**
 * 比较器01
 * 所有内容升序排序
 */
class ComparatorMachine01 implements Comparator<Student2> {
    @Override
    public int compare(Student2 o1, Student2 o2) {
        int i = o1.getNumber() - o2.getNumber();
        int j = o1.getAge() - o2.getAge();
        int k = o1.getName().compareTo(o2.getName());
        return i != 0 ? i : (j != 0 ? j : k);
    }
}

/**
 * 比较器03
 */
class ComparatorMachine03 implements Comparator<Student2> {
    @Override
    public int compare(Student2 o1, Student2 o2) {
        int i = o1.getNumber() - o2.getNumber();
        int j = o1.getAge() - o2.getAge();
        int k = o1.getName().compareTo(o2.getName());
        //返回正数则排序时o2放前面;返回负数则o2放后面
        return i != 0 ? i : (j != 0 ? -j : k);
    }
}

关于compare方法的使用规则:

o1和o2为两个将要进行比较的数据。返回正数则表示o2因该排在o1前面,返回负数则表示o2应该排在o1后面,返回0则表示两个没有前后之分。若方法体中只写return一个正数,则这组数据排列顺序不变,如果只写return一个负数,则将原来的排列顺序进行反转。

(name采用String类的compareTo方法,即按照字符在字典中的顺序排序。)

·接下来写一个测试类实现上述需求:

public class ComparatorDemo {
    public static void main(String[] args) {
        Student2[] stuArr2 = {
                new Student2(18, 101, "张三"),
                new Student2(18, 101, "张三子"),
                new Student2(19, 101, "李四"),
                new Student2(19, 102, "张四"),
                new Student2(18, 103, "张十三"),
                new Student2(17, 103, "王五")
        };
        //调用java.util.Arrays.sort方法,传入待排序的数组和符合需求的比较器对象
        Arrays.sort(stuArr2, new ComparatorMachine01());//调用比较器01 实现升序排序
        for (Student2 student : stuArr2) {
            System.out.println(student);
        }
        System.out.println();
        //采用Lambda表达式
        Arrays.sort(stuArr2, (o1, o2) -> {
            int i = o1.getNumber() - o2.getNumber();
            int j = o1.getAge() - o2.getAge();
            int k = o1.getName().compareTo(o2.getName());
            return i != 0 ? -i : (j != 0 ? -j : -k);
        });
       /* 等价于下面代码(以内部类形式)
            Arrays.sort(stuArr2, new Comparator<Student2>() {
            @Override
            public int compare(Student2 o1, Student2 o2) {
                int i = o1.getNumber() - o2.getNumber();
                int j = o1.getAge() - o2.getAge();
                int k = o1.getName().compareTo(o2.getName());
                return i != 0 ? -i : (j != 0 ? -j : -k);
            }
        });*/
        for (Student2 student : stuArr2) {
            System.out.println(student);
        }
        System.out.println();
        //调用比较器03 实现number升序,age降序,name升序
        Arrays.sort(stuArr2, new ComparatorMachine03());
        for (Student2 student : stuArr2) {
            System.out.println(student);
        }
    }
}

运行结果:

我们可以发现,如果需要对一组数据进行多种规则的排序,选择Comparator接口更合适。 

(文章略显粗糙,若有错误,烦请批评指正!)

 

标签:Comparable,Java,name,自定义,int,Student2,age,number,o2
来源: https://blog.csdn.net/weixin_58464994/article/details/120684632

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有