Java中经常会涉及到对象数组的排序问题,那么就涉及到对象之间的比较问题,Java实现对象排序的两种方式:

🔸自然排序 java.lang.Comparable

🔸定制排序 java.util.Comparator

(由于还没有学习泛型,所以暂时忽略掉泛型的概念,在涉及到泛型的地方都使用Object类)

1️⃣Comparable 接口

方法:将需要排序的对象的类去实现Comparable接口,重写compareTo(obj)方法,这样调用Arrays.sort(arr)时即可按照实现好的比较规则对该对象数组进行排序

像String、包装类等都实现了Comparable接口,重写了compareTo(obj)方法,给出了比较两个对象的规则

重写compareTo(obj)的规则(sort是从小到大的排序):

如果当前对象this大于形参对象obj,则返回正整数;

如果当前对象this小于形参对象obj,则返回负整数;

如果当前对象this等于形参对象obj,则返回零;

为什么叫自然排序:排序方法在设计类的时候一同设计,在对对象数组进行排序的时候,自动调取类中的比较方法,自然而然~

import java.util.Arrays;
/**
* @Author: ssy
* @Description:
* @Date: Created in 9:30 2020/11/26
* @Modified By:
*/
public class ComparableTest {
public static void main(String[] args) {
Good[] goods=new Good[4];
goods[0]=new Good(13.6,"apple");
goods[1]=new Good(5.4,"banana");
goods[2]=new Good(6.3,"orange");
goods[3]=new Good(12.3,"peach");
Arrays.sort(goods);
System.out.println(Arrays.toString(goods));
}
}
class Good implements Comparable{
double price;
String name;
public Good() {
}
public Good(double price, String name) {
this.price = price;
this.name = name;
}
@Override
public int compareTo(Object o) { //此处忽略泛型的使用,只讲比较方法
if(o instanceof Good){
Good good=(Good)o;
if(this.price>good.price){
return 1;
}
else if(this.price
return -1;
}
else return 0;
//错误写法 return this.price-good.price 因为price是double类型的
}
throw new RuntimeException("传入的数据类型不一致!");
}
@Override
public String toString() {
return "Good{" +
"price=" + price +
", name='" + name + '\'' +
'}';
}
}

支持多级比较,例如当price相等时,可以继续以name为标准进行比较

2️⃣java.util.Comparator

适用场景:

当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码(例如java库中的一些类)

或者实现了java.lang.Comparable接口的排序规则不适合当前的操作

那么可以使用Comparator定制排序方法

方法:

创建Comparator接口的实现类(可以显式,也可以使用匿名类),重写compare(Object o1,Object o1)方法,定义对象比较的规则

可将Comparator的实现类传递给sort方法(Collections.sort或者Arrays.sort),从而允许在排序顺序上实现精准控制

下面的例子有两个注意点:

①使用了泛型(区别在于可以直接使用Good这种具体的类代替通用的Object)

②使用了新的比较方式,直接调用了String内部实现的compareTo方法

public class ComparatorTest {
public static void main(String[] args) {
Good[] goods=new Good[4]; //Good类在上面的代码中有定义
goods[0]=new Good(13.6,"apple");
goods[1]=new Good(5.4,"banana");
goods[2]=new Good(6.3,"orange");
goods[3]=new Good(12.3,"peach");
Arrays.sort(goods, new Comparator() {
@Override
public int compare(Good o1, Good o2) {
return o1.name.compareTo(o2.name);
}
});
System.out.println(Arrays.toString(goods));
}
}

🔊Comparable和Comparator的区别

Compareble接口的方式一旦类实现了它,保证Compareble接口实现类的对象在任何位置都可以直接比较大小。

Comparator接口属于临时性的比较规格,需要在sort函数中作为参数传递。