Java中易混淆的两个接口:Comparable和Compara

2020-03-11  本文已影响0人  shenghaishxt

Comparable接口定义

Comparable是排序接口,如果一个类实现了Comparable接口,意味着这个类是支持排序的,即实现这个类的对象的List或Array可以通过Collections.sort或Arrays.sort进行排序。

Comparable接口来自java.lang包,它仅仅只有一个方法:

package java.lang;

public interface Comparable<T> {
    int compareTo(T var1);
}

这个方法的意思是,假设我们使用x.compareTo(y)来比较xy的大小,若返回负数,意味着x小于y;若返回正数,意味着x大于y;若返回0,意味着两者相等。

Comparator接口定义

Comparator是比较器接口,在我们需要控制某个没有实现Comparable接口的类的次序时使用。

Comparator接口在Java8中进行了较大的改进,在Java8之前Comparator接口也仅只有两个函数:compare()和equals(),但在Java8中达到了18个方法。不过,其余的方法都是接口的default方法以及static静态方法,所以并不需要在实现时额外实现。对于equals方法,其实也不需要额外的实现。原因是所有类都继承自java.lang.Object这个类,而Object中已经实现了equals方法,那么我们的这个匿名内部类自然不需要实现equals方法。所以在实现Comparator接口时,必须实现的只有Compare方法。

Java中比较器升序降序的实现

对于compare方法,它与compareTo方法类似。在自定义比较器时,总是将升序降序弄混,有必要总结一下。

public int compare(Customer o1, Customer o2) {}

这个函数有两个参数用于比较:

下面用一段实现Comparator用作匿名内部类的代码作为举例:

import java.util.*;

public class Customer {
    private String name;
    private int age;

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

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

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

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

    public static void main(String[] args) {
        Customer customer1 = new Customer("James", 23);
        Customer customer2 = new Customer("Durante", 35);
        List<Customer> list = new ArrayList<>();
        list.add(customer1);
        list.add(customer2);

        list.sort(new Comparator<Customer>() {
            @Override
            public int compare(Customer o1, Customer o2) {
                // 若返回负数,表示不需要交换o1和o2的位置
                // return o1.age - o2.age;
                // 若返回正数,表示需要交换o1和o2的位置
                return o2.age - o1.age;
            }
        });
        for (Customer customer : list)
            System.out.println("name: " + customer.getName() + " age: " + customer.getAge());
    }
}

得到的结果为:

name: Durante age: 35
name: James age: 23

解释一下,这个函数中的重写的compare方法用于实现降序:

  1. 在这个函数中,若o1.age > o2.age,那么o2.age - o1.age < 0,返回负数,不需要交换o1和o2的顺序,降序

  2. 同样,若o1.age < o2.age,那么o2.age - o1.age > 0,返回正数,需要交换o1和o2的顺序,还是降序。

总结

Java中有两种排序方式:

  1. Comparable 是自然排序。(在实体类中实现)
  2. Comparator 是定制排序。(不修改实体类,直接在调用方创建)

一些普通数据类型已经实现了Comparable接口,如String, Integer, Double等,我们可以直接调用。而对于一些我们自定义的类,在不同的情况下可能需要不同的比较策略,不能在类中将Comparable定死,这时候通常在调用方创建Comparator进行定制排序。

over~

上一篇 下一篇

猜你喜欢

热点阅读