Java 比较器Comparable 和 Comparator详解

Java 比较器Comparable 和 Comparator详解

目录

Java 比较器Comparable 和 Comparator详解

1、概述

2、Comparable 和 Comparator 实例演示

3、总结

 


1、概述

Comparable 和 Comparator接口都可以用来实现集合中元素的比较、排序

Comparator位于包java.util下,而Comparable位于包java.lang下,Comparable接口将比较代码嵌入自身类中,而后者在一个独立的类中实现比较。
       像Integer、String等这些基本类型的Java封装类都已经实现了Comparable接口,这些类对象本身就支持自比较,直接调用Collections.sort()就可以对集合中元素的排序,无需自己去实现Comparable接口。
       而有些自定义类的List序列,当这个对象不支持自比较或者自比较函数不能满足你的要求时,你可以写一个比较器来完成两个对象之间大小的比较,也就是指定使用Comparator(临时规则排序,也称作专门规则排序),如果不指定Comparator,那么就用自然规则排序,这里的自然顺序就是实现Comparable接口设定的排序方式。

 注意:如果一个对象没有实现Comparator 和Comparable接口 ,就不能进行排序,否则会报错java.lang.ClassCastException。

2、Comparable 和 Comparator 实例演示

      (1)定义了一个Car类,他有三个属性,车名,价格,生产年份。并实现了Comparable 实现了一个compareTo方法,按照车的价格进行排序。

public class Car implements Comparable{
    private String name;
    private int price;
    private int age;
    
    public Car(String name , int price , int age){
        this.name = name;
        this.price = price;
        this.age = age;
    }
    

    public String getName() {
        return name;
    }

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

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
       @Override
    public String toString() {
        return "Car{" +
                "name='" + name + '\'' +
                ", price=" + price +
                ", age=" + age +
                '}';
    }
    @Override
    public int compareTo(Car car) {
        return this.price - car.price;
    }
}

(2)测试类。实现按照车的价格进行排序。

 

import java.util.ArrayList;
import java.util.Arrays;

public class Test {
    public static void main(String args[]){
        ArrayList list = new ArrayList<>();
        list.add(new Car("宝马" , 12 , 2019));
        list.add(new Car("大众" , 10 , 2015));
        list.add(new Car("蓝比基尼" , 50 , 2018));
        Car[] cars = list.toArray(new Car[list.size()]);
        Arrays.sort(cars);
        for(Car car : cars){
            System.out.println(car);
        }
    }
}

结果:

Car{name='大众', price=10, age=2015}
Car{name='宝马', price=12, age=2019}
Car{name='蓝比基尼', price=50, age=2018}

(3)如果我想按照车的生产年份进行从大到小的排序呢。有两种方法,一种就是重新修改Car类中的compareTo方法。第二种方法就是使用Comparator 创建一个外部排序,实现compare方法。如下:

public class Test {
    public static void main(String args[]){
        ArrayList list = new ArrayList<>();
        list.add(new Car("宝马" , 12 , 2019));
        list.add(new Car("大众" , 10 , 2015));
        list.add(new Car("蓝比基尼" , 50 , 2018));
        Car[] cars = list.toArray(new Car[list.size()]);

        Arrays.sort(cars, new Comparator() {//添加一个外部排序器即可
            @Override
            public int compare(Car car, Car t1) {
                return t1.getAge() - car.getAge();
            }
        });
        for(Car car : cars){
            System.out.println(car);
        }
    }
}

结果:

Car{name='宝马', price=12, age=2019}
Car{name='蓝比基尼', price=50, age=2018}
Car{name='大众', price=10, age=2015}

哈哈,是不是感觉Comparable 和 Comparator 就那样。。。。。。。

3、总结

两种比较器的区别

 (1)Comparable是排序接口,若一个类实现了Comparable接口,就意味着“该类支持排序”。而Comparator是比较器,我们若需要控制某个类的次序,可以建立一个“该类的比较器”来进行排序。

 (2)Comparable相当于“内部比较器”,而Comparator相当于“外部比较器”。

 (3)两种方法各有优劣, 用Comparable 简单, 只要实现Comparable 接口的对象直接就成为一个可以比较的对象,但是需要修改源代码。 用Comparator 的好处是不需要修改源代码, 而是另外实现一个比较器, 当某个自定义的对象需要作比较的时候,把比较器和对象一起传递过去就可以比大小了, 并且在Comparator 里面用户可以自己实现复杂的可以通用的逻辑,使其可以匹配一些比较简单的对象,那样就可以节省很多重复劳动了。

如何确认比价的类型

(1)如果我们是用方法中的前者减去后者,那么可以认为是升序,即从小到大。如上面的第一个实例:

    @Override
    public int compareTo(Car car) {   //升序排序
        return this.price - car.price;
    }

2)如果我们是用方法中的前者减去后者,那么可以认为是升序,即从小到大。如上面的第二个实例:

 Arrays.sort(cars, new Comparator() {//添加一个外部排序器即可
            @Override
            public int compare(Car car, Car t1) {
                return t1.getAge() - car.getAge();  //降序排序
            }
        });

 

 

 

 

你可能感兴趣的:(Java基础,java)