跳转至

1. 比较器

Arrays

java.util.Arrays是一个Java系统里面提供的数组操作类,在该类中支持了

  • 二分查找对象 : static int binarySearch(Object[] a, Object key)

  • 数组比较 : static boolean equals(Object[] a, Object[] a2)

  • 数组填充 : static void fill(Object[] a, Object val)

  • 数组排序 : static void sort(Object[] a)

class Ball{
    private String brand;
    private double price;

    public Ball(String brand, double price) {
        this.brand = brand;
        this.price = price;
    }
}

public class ArraysDemo {
    public static void main(String[] args) {
        Ball[] balls = {
                new Ball("足球", 199),
                new Ball("排球", 299),
                new Ball("篮球", 99),
                new Ball("台球", 999),
                new Ball("乒乓球", 59)
        };
        Arrays.sort(balls);
        System.out.println(Arrays.toString(balls));
    }
}

报错 : ComparableTimSort

Exception in thread "main" java.lang.ClassCastException: Ball cannot be cast to java.base/java.lang.Comparable
    at java.base/java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:320)
    at java.base/java.util.ComparableTimSort.sort(ComparableTimSort.java:188)
    at java.base/java.util.Arrays.sort(Arrays.java:1248)
    at ArraysDemo.main(ArraysDemo.java:47)

2. Comparable 接口

Comparable 是在开发中用于区分对象大小关系最为常用的一种排序接口 , 其定义如下

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

如果先实现自定义类的对象数组排序操作 , 那么就必须实现Comparable接口

范例 :

import java.util.Arrays;

class Ball implements Comparable<Ball>{
    private String brand;
    private double price;

    // 省略setter getter toString 和 有参构造

    @Override
    public int compareTo(Ball o) {
        if (this.price-o.price > 0) return 1;
        else if (this.price-o.price == 0) return 0;
        else   return -1;
    }
}
public class ArraysDemo {
    public static void main(String[] args) {
        Ball[] balls = {
                new Ball("足球", 199.0),
                new Ball("排球", 299.2),
                new Ball("篮球", 99.3),
                new Ball("台球", 999.4),
                new Ball("乒乓球", 59.5)
        };
        Arrays.sort(balls);
        System.out.println(Arrays.toString(balls));
    }
}

并不是所有的类都要事先Comparable接口 , 而是需要进行数组排序的类实现 Comparable 即可 .

3. Comparator 接口

假如在一个类在生成的是否没有实现Comparable , 在使用一段时间后 , 需要添加排序 , 但是又不能对原有的类进行更改 , 这时候就需要使用java.util.Comparator接口

Comparator接口定义如下 :

@FunctionalInterface
public interface Comparator<T> {
    int compare(T o1, T o2); // 主要使用 1.8之前只有这个方法
    // 其他方法
}

范例 :

package comparator;

import java.util.Arrays;
import java.util.Comparator;

class Ball {
    private String brand;
    private double price;

    // 省略setter getter toString 和 有参构造
}
class BallComparator implements Comparator<Ball> {

    @Override
    public int compare(Ball o1, Ball o2) {
        /*if (o1.getPrice()-o2.getPrice() > 0) return 1;
        else if (o1.getPrice()-o2.getPrice() == 0) return 0;
        else   return -1;*/
    }
}
public class ComparatorDemo {
    public static void main(String[] args) {
        Ball[] balls = {
                new Ball("足球", 199.0),
                new Ball("排球", 299.2),
                new Ball("篮球", 99.3),
                new Ball("台球", 999.4),
                new Ball("乒乓球", 59.5)
        };
        // Arrays.sort(balls); // 无法使用此方法排序
        Arrays.sort(balls, new BallComparator());
        // 翻转排序
        Arrays.sort(balls, new BallComparator().reversed());
        // λ表达式
        Comparator<Ball> comparator = (o1, o2) -> {
            if (o1.getPrice() - o2.getPrice() > 0) return 1;
            else if (o1.getPrice() - o2.getPrice() == 0) return 0;
            else return -1;
        };
        Arrays.sort(balls, comparator);
        System.out.println(Arrays.toString(balls));
    }
}

结果

[Ball{brand='乒乓球', price=59.5}
, Ball{brand='篮球', price=99.3}
, Ball{brand='足球', price=199.0}
, Ball{brand='排球', price=299.2}
, Ball{brand='台球', price=999.4}
]

4. 总结

区别 :

  • java.lang.Comparable : 在类定义的时候实现的接口 , 实现comparaTo()方法用于确认大小关系 , 属于类的原生比较方法
  • java.util.Comparator : 不用再类定义的时候定义该接口的实现 , 而是在要使用的时候创建一个专门确认大小关系的类 , 在JDK1.8之后 , 更加灵活 , 因为引入了 lanmbda表达式