比较器Comparable和Comparator

目录

  1. 作用
  2. 区别
  3. Comparable使用
  4. Comparator的使用
  5. 总结

  • 作用

Java的Comparable和Comparator当需要排序的集合或数组不是单纯的数字型时,通常可以使用Comparator或Comparable,以简单的方式实现对象排序或自定义排序。


  • 区别

一、Comparable 
           强行对实现它的每个类的对象进行整体排序,实现此接口的对象列表(和数组)可以通过Collections.sort或Arrays.sort进行自动排序。Comparable是一个内比较器,实现了Comparable接口。是可以和自己比较的。Comparable接口的类的比较,则依赖compareTo方法来实现,compareTo方法也被称为自然比较方法。如果add一个Collection的对象想时想要Collections的sort方自动进行排序的话,那么这个对象必须实现Comparable接口,并重写compareTo方法。compareTo方法有一个参数,返回值是int,有三种情况:

1、新添加进来的对象实例大于已经存在的对象时,返回正整数 1 。表示不同的实例对象,添加至已存在对象的后面。

2、新添加进来的对象实例等于已经存在的对象时,返回 0。表示重复对象实例,则不被添加。

3、新添加进来的对象实例小于已经存在的对象时,返回负整数 -1。表示不同的实例对象,添加至已存在对象的前面。

二、Comparator  

强行对某个对象collection进行整体排序的比较函数,可以将Comparator传递给Collections.sort或Arrays.sort。Comparator是一个外比较器,它的比较则是通过重写compare方法来实现的。方法有两个参数T o1和T o2,是泛型的表示方式,分别表示待比较的两个对象,o1表示要添加的新的对象实例,o2表示已经添加进来的对象实例,返回值也是int,分三种情况:

1、o1大于o2,返回正整数 1 。表示不同的实例对象,添加至已存在对象的后面。

2、o1等于o2,返回 0。表示重复对象实例,则不被添加。

3、o1小于o3,返回负整数 -1。表示不同的实例对象,添加至已存在对象的前面。


 

  • Comparable的使用

定义一个类,并实现Comparable接口,重写compareTo方法,根绝返回值编写自己的比较规则。

具体代码实现:


package com.vince;

public class Animal1 implements Comparable<Animal1>{
    private String name;
    private String color;
    private Float weight;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
    public Float getWeight() {
        return weight;
    }
    public void setWeight(Float weight) {
        this.weight = weight;
    }
    public Animal1(String name, String color, Float weight) {
        super();
        this.name = name;
        this.color = color;
        this.weight = weight;
    }
    @Override
    public String toString() {
        return "名字:" + name + "\t颜色:" + color + "\t体重:" + weight;
    }

//按照体重对动物升序排列
    @Override
    public int compareTo(Animal1 o) {
        // 判断对象是否为空,为空则不添加
        if(o == null) {
            return 0;
        }
        if(this.weight >= o.getWeight()) {
            return 1;// 对象不为空,如果体重大的则排到后面
        }else {
            return -1;// 对象不为空,如果体重小的则排到前面
        }
    }    
}

package test;
import java.util.Set;
import java.util.TreeSet;
import com.vince.Animal1;
public class Test2 {
    public static void main(String[] args) {
        // TODO
        Set<Animal1> animals = new TreeSet<>();
        animals.add(new Animal1("Monkey", "black", 90f));
        animals.add(new Animal1("Duck", "yellow", 5f));
        animals.add(new Animal1("Chicken", "white", 7f));
        animals.add(new Animal1("Goldfish", "golden", 2f));
        animals.add(new Animal1("Elephant", "gray", 250f));
        System.out.println("内部比较器升序排序后的结果为:");
        for (Animal1 animal : animals) {
            System.out.println(animal);
        }
    }
}

  • Comparator

匿名的方式实现Comparator:在创建一个类时,不直接在类当中去实现,而是在测试类中采用匿名内部类的方式,直接创建一个Comparator来实现comparable方法。

具体代码实现:


package com.vince;

public class Animal2 {
    private String name;
    private String color;
    private Float weight;

    public String getName() {
        return name;
    }

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

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public Float getWeight() {
        return weight;
    }

    public void setWeight(Float weight) {
        this.weight = weight;
    }

    public Animal2(String name, String color, Float weight) {
        super();
        this.name = name;
        this.color = color;
        this.weight = weight;
    }

    @Override
    public String toString() {
        return "名字:" + name + "\t颜色:" + color + "\t体重:" + weight;
    }
}

package test;

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
import com.vince.Animal2;

public class Test3 {

    public static void main(String[] args) {
        // 匿名内部类的方式实现比较器降序排序
        Set<Animal2> animal2s = new TreeSet<Animal2>(new Comparator<Animal2>() {
            @Override
            public int compare(Animal2 o1, Animal2 o2) {
                // 如果对象都为空则不添加 
                if(o1 == null || o2 == null) {
                    return 0;
                }
                if(o1.getWeight() >= o2.getWeight()) {
                    return -1;//体重大的放前面
                }else {
                    return 1;//体重小的放前面
                }
            }
        });
        animal2s.add(new Animal2("Monkey", "black", 90f));
        animal2s.add(new Animal2("Duck", "yellow", 5f));
        animal2s.add(new Animal2("Chicken", "white", 7f));
        animal2s.add(new Animal2("Goldfish", "golden", 2f));
        animal2s.add(new Animal2("Elephant", "gray", 250f));
        System.out.println("外部比较器降序排列后的结果为:");
        for (Animal2 animal : animal2s) {
            System.out.println(animal);
        }       
    }

}

自定义比较器Comparator:另外创建一个比较器类直接在类里面实现compare方法,在测试类直接new一个Comparator。

具体代码实现:

package com.vince;

public class Student {
        private Integer classNumber;
        private String name;
        private char sex;
        private Integer age;

        public Integer getClassNumber() {
            return classNumber;
        }
        public String getName() {
            return name;
        }
        public char getSex() {
            return sex;
        }
        public Integer getAge() {
            return age;
        }
        public Student(Integer classNumber, String name, char sex, Integer age) {
            super();
            this.classNumber = classNumber;
            this.name = name;
            this.sex = sex;
            this.age = age;
        }
        @Override
        public String toString() {
            return "班级编号:" + getClassNumber() + "\t姓名:" + getName() + "\t性别:" + sex + "\t年龄:" + age;
        }
}

package comparator;

import java.util.Comparator;

import com.vince.Student;

public class StudentComparator implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        // TODO 
        if(o1.getAge() == o2.getAge()) {
            return 0;
        }
        if(o1.getAge() >= o2.getAge()) {
            return 1;
        }else {
            return -1;
        }
    }
}

package test;

import java.util.TreeSet;

import com.vince.Student;

import comparator.StudentComparator;

public class Test4 {
    public static void main(String[] args) {
        
        TreeSet<Student> treeSet = new TreeSet<>(new StudentComparator());
        treeSet.add(new Student(1,"小明",'男',22));
        treeSet.add(new Student(5,"小白",'男',20));
        treeSet.add(new Student(3,"木子",'女',45));
        treeSet.add(new Student(3,"木子",'女',45));
        treeSet.add(new Student(7,"小绿",'女',32));
        treeSet.add(new Student(1,"小明",'男',22));
        for (Student student : treeSet) {
            System.out.println(student);
        }
    }
}

  • 总结: 

比较器是把集合或数组的元素强行按照指定方法进行排序的对象,它是实现了Comparator接口类的实例。如果一个集合元素是可比较的(实现了Comparable接口),那么就具有了默认排序方法,比较器则是强行改变它默认的比较方式来进行排序。或者有的集合元素不可比较(没有实现Comparable接口),则可用比较器来实现动态的排序。

相同点:Comparable和Comparator可以按照指定方法,对对象实现动态的排序。他们实现排序的方法的返回值都是int类型,分为三种情况:1、0和-1。

不同点:Comparable的排序依赖的是compareTo方法,且参数只有一个。Comparator的排序依赖的是compare,传入参数有两个,可以通过匿名内部类或者单独实现。Comparator接口一般不会被集合元素类所实现,而是单独实现或者匿名内部类方式实现。

猜你喜欢

转载自blog.csdn.net/m0_37914799/article/details/81370100