【JavaSE】---Comparable接口与Comparator

【JavaSE】---Comparable接口与Comparator比较器

一、Comparable接口

1、Comparable接口的定义

image-20210921124851326可以看出这个接口是通过泛型定义的,作用就是用来指定某一对象的排序规则的。

返回值:

1:表示大于
-1:表示小于
0:表示相等

2、实际案例

以下内容参考:

版权声明:本文为CSDN博主「南淮北安」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/nanhuaibeian/article/details/104169002

设计一个学生类,包含姓名、年龄、成绩,并产生一个对象数组,要求按成绩由高到底排序,如果成绩相等,则按年龄由低到高排序。
此时如果直接编写排序操作会比较麻烦,所以可以==使用 Arrays 类中的 sort() 方法进行排序操作。

import java.util.Arrays;

class Student implements Comparable<Student>{//指定类型为 Student
    private String name;
    private int age;
    private float score;
    public Student(String name,int age,float score){
        this.name = name;
        this.age = age;
        this.score = score;
    }
    public String toString(){
        return name + "\t\t" + age + "\t\t" + score;
    }
    public int compareTo(Student stu){
        //覆写 compareTo() 方法,实现排序规则的应用
        if (this.score>stu.score){
            return -1;
        }else if(this.score < stu.score){
            return 1;
        }else {
            if (this.age > stu.age){
                return 1;
            }else if (this.age<stu.age){
                return -1;
            }else {
                return 0;
            }
        }
    }

}
public class Root{
    public static void main(String[] args) {
        Student[] stu = {new Student("stu1",20,90.0f),
        new Student("stu2",22,90.0f),
        new Student("stu3",20,70.0f),
        new Student("stu4",34,98)};
        Arrays.sort(stu);
        for (Student x:stu){
            System.out.println(x);
        }
    }
}

image-20210921125215145

3、比较器的排序原理

这里博主写的太好了,忍不住做个笔记,抄下作业。

排序过程实际上就是数据结构中的二叉树排序方法,通过二叉树进行排序,然后利用中序遍历的方式把内容依次读取出来。

image-20210921125639785

image-20210921125649910

class BinaryTree{
    class Node{//声明一个节点类
        private Comparable data;//保存具体的内容
        private Node left;
        private Node right;
        public void addNode(Node newNode){
            //要确定是放在左子树还是右子树
            if(newNode.data.compareTo(this.data)<0){
                if(this.left == null){//放在左子树
                    this.left = newNode;
                }else {
                    this.left.addNode(newNode);
                }
            }
            if (newNode.data.compareTo(this.data)>=0){
                if(this.right == null){ //放在右子树
                    this.right = newNode;
                }else {
                    this.right.addNode(newNode);
                }
            }
        }
        public void printNode(){//输出时采用中序遍历
            if (this.left != null){//先输出左子树
                this.left.printNode();
            }
            System.out.print(this.data + "\t");//再输出根节点
            if (this.right !=null){
                this.right.printNode();
            }
        }
    }
    private Node root;
    public void add(Comparable data){
        Node newNode = new Node();//每传入一个新的内容就声明一个根节点
        newNode.data = data;
        if(root == null){
            root = newNode;//如果是第1个元素,设置成根元素
        }else{
            root.addNode(newNode);//确定节点是放在左子树还是右子树
        }
    }
    public void print(){//输出节点
        this.root.printNode();
    }
}
public class Test{
    public static void main(String[] args) {
        BinaryTree bt = new BinaryTree();
        bt.add(8);
        bt.add(3);
        bt.add(3);
        bt.add(10);
        bt.add(9);
        bt.add(1);
        bt.add(5);
        bt.add(5);//加入重复元素
        System.out.println("排序之后的结果:");
        bt.print();
    }
}

二、Comparator比较器

1、介绍

  • comparatorjavase中的接口,位于java.util包下,该接口抽象度极高,有必要掌握该接口的使用
  • 大多数文章告诉大家comparator是用来排序,但我想说排序是comparator能实现的功能之一,他不仅限于排序

2、使用场景

  1. 排序,需要比较两个对象谁排在前谁排在后(排序也可以让类实现Comparable接口,实现后该类的实例也具有排序能力)。
  2. 分组,需要比较两个对象是否是属于同一组。

3、排序场景

​ 在List或数组中的对象如果没有实现Comparable接口时,那么就需要调用者为需要排序的数组或List设置一个Compartor,Compartor的compare方法用来告诉代码应该怎么去比较两个实例,然后根据比较结果进行排序。

https://www.cnblogs.com/MrYuChen-Blog/p/14012428.html

4、但一条件排序

①Dog基类

public class Dog {
    public int age;
    public String name;
    public String num;

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

    public Dog() {
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getNum() {
        return num;
    }

    public void setNum(String num) {
        this.num = num;
    }

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

②单一条件排序测试

import java.text.Collator;
import java.util.*;

public class OneSort {

    public static void main(String[] args) {

        List<Dog> dogList= new ArrayList<Dog>(){
            {
                add(new Dog(5, "DogA","001"));
                add(new Dog(5, "DogB","002"));
                add(new Dog(5, "DogC","003"));
                add(new Dog(9, "DogA","004"));
                add(new Dog(35, "DogF","005"));
                add(new Dog(74, "DogG","006"));
            }
        };

        test1(dogList);
        System.out.println("给狗子按照年龄倒序:"+dogList);

        test2(dogList);
        System.out.println("给狗子按照名字排序:"+dogList);
    }

    /**
     * 单一条件排序
     */

    public static void test1(List a){
        Collections.sort(a, new Comparator<Dog>() {
            //实现compare(T o1, To2) 方法,返回正数,零,负数各代表大于,等于小于
            @Override
            public int compare(Dog o1, Dog o2) {
                return o2.age - o1.age; //排序规则----升序
            }
        });
    }

    public static void test2(List a){
        //按照名字排序
        Collator comparator = Collator.getInstance(Locale.CANADA);

        Collections.sort(a, new Comparator<Dog>() {
            @Override
            public int compare(Dog o1, Dog o2) {
                return comparator.compare(o1.getName(),o2.getName());
            }
        });

    }
}

③Lambda

 /**
     *使用Lambda表达式优化比较器代码(单一条件排序)
     */
    @Test
    public void test3() {
        //对学生集合按年龄进行排序
        Collections.sort(list,(s1, s2) -> (s1.getAge() - s2.getAge()) );
    }

5、多条件排序

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class SecondSort {

    public static void main(String[] args) {
        List<Dog> dogList= new ArrayList<Dog>(){
            {
                add(new Dog(5, "DogA","001"));
                add(new Dog(5, "DogB","002"));
                add(new Dog(5, "DogC","003"));
                add(new Dog(9, "DogA","004"));
                add(new Dog(35, "DogF","005"));
                add(new Dog(74, "DogG","006"));
            }
        };

        test1(dogList);
        System.out.println("年龄多条件:"+dogList);
    }

    public static void test1(List a){
        Collections.sort(a, new Comparator<Dog>() {

            @Override
            public int compare(Dog o1, Dog o2) {
                int flag;
                // 首选按年龄升序排序
                flag = o1.getAge()-o2.getAge();
                if(flag==0){
                    // 如果年龄按编号降序排序
                    flag = o2.getNum().compareTo(o1.getNum());
                }
                return flag;
            }
        });
    }
}
posted @ 2021-09-21 13:18  DarkerG  阅读(49)  评论(0编辑  收藏  举报