0. 为什么需要Java比较器
一般情况下对象之间只能使用==或!=比较,而不能使用算数运算符进行大小比较。但是实际情况中,需要涉及对象之间的比较。
此时需要实现两个接口中的任何一个:Comparable或Comparator
Java实现对象排序的方式有两种:
- 自然排序:java.lang.Comparable
- 定制排序:java.util.Comparator
1. Comparable接口(自然排序)
1.1 举例
- 像String、包装类实现了Comparable接口,重写了compareTo()方法,给出了比较两个对象的方法
1.2 重写compareTo的规则
- 如果当前对象this大于形参对象obj,则返回正整数
如果当前对象this小于形参对象obj,则返回负整数
如果相等,则返回零
String[] arr = new String[]{"c","a","o","i"};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
1.3 自定义类实现Comparable接口,重写compareTo()方法
自定义类如果也想使用Arrays.sort(),工具类中的排序方法,需要实现Comparable接口,重写compareTo()方法
自定义类实现Comparable接口
重点关注compareTo()方法的重写
//实现Comparable接口
public class Goods implements Comparable {
private String name;
private int price;
public Goods(String name, int price) {
this.name = name;
this.price = price;
}
//实现compareTo()方法
@Override
public int compareTo(Object o) {
if (o instanceof Goods) {
Goods goods = (Goods) o;
if (this.price > goods.price) {
return 1;
} else if (this.price < goods.price) {
return -1;
} else {
return 0;
}
}
throw new RuntimeException("传入的数据类型不是Goods类的对象");
}
@Override
public String toString() {
return "Goods{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
}
然后就可以使用Arrays工具类中的sort()方法进行排序了
Goods[] arr = new Goods[3];
arr[0] = new Goods("可乐",20);
arr[1] = new Goods("雪碧",10);
arr[2] = new Goods("芬达",5);
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
2. Comparator接口(定制排序)
当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,
或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,
那么可以考虑使用 Comparator 的对象来排序,强行对多个对象进行整体排序的比较。
实现compare方法
在Arrays.sort()方法中创建Comparator的匿名类的匿名对象,实现compare方法,实现比较的定制
- 将字符串按从大到小的方式排序
String[] arr = new String[]{"c","a","o","i"};
//创建Comparator的匿名对象
Arrays.sort(arr, new Comparator(){
//实现compare方法
@Override
public int compare(Object o1, Object o2) {
if(o1 instanceof String&& o2 instanceof String){
String str1 = (String) o1;
String str2 = (String) o2;
//将字符串按从大到小的方式排序
return -str1.compareTo(str2);
}
//return 0;
throw new RuntimeException("输入的数据类型不一致");
}
});
System.out.println(Arrays.toString(arr));
- 自定义类实现Comparator接口
//实现Comparator接口(定制排序)
@Test
public void test4() {
Goods[] arr = new Goods[3];
arr[0] = new Goods("kele", 20);
arr[1] = new Goods("xuebi", 10);
arr[2] = new Goods("fenda", 5);
Arrays.sort(arr, new Comparator() {
//指明商品比较大小的方式:
//按照产品名称从低到高排序,
// 再按照价格从高到低排序
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Goods && o2 instanceof Goods) {
Goods g1 = (Goods) o1;
Goods g2 = (Goods) o2;
if (g1.getName().equals(g2.getName())) {
return -Double.compare(g1.getPrice(), g2.getPrice());
} else {
return g1.getName().compareTo(g2.getName());
}
}
throw new RuntimeException("输入的数据类型不一致");
}
});
System.out.println(Arrays.toString(arr));
}
3. Comparable接口和Comparator的对比
- Comparable是通过具体的类去实现的,Comparable接口的方式一旦指定,保证Comparable实现类的对象在任何位置都是可以比较大小的。
- Comparator接口属于临时性的创建的比较方式
是在Arrays.sort中创建的匿名子类的匿名对象
Arrays.sort(arr,new Comparator(){
public void int compare(){
//实现compare方法
return 0;
}
});