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表达式