Java中的对象,正常情况下只能进行比较:== 或 !=。不能使用 > 或 < 的,但是在开发场景中,我们需要对多个对象进行排序,言外之意,就需要比较对象的大小。如何时间? ==> 两个接口:Comparable 或 Comparator。
1. Comparable 接口
1.1 String 和包装类
Comparable 中只含有一个抽象方法:compareTo。接口源码如下:
public interface Comparable<T> {
public int compareTo(T o);
}
- 像 String、包装类 等实现了 Comparable 接口,都重写了 compareTo 方法,各自有各自的比较方法。
- String、包装类 重写 compareTo(obj) 方法,让它进行了从小到大的升序排列,String是按字典序。
- 重写 compareTo(obj) 的规则为:
- 如果当前对象 this 大于形参对象 obj,则返回正整数
- 如果当前对象 this 小于形参对象 obj,则返回负整数
- 如果当前对象 this 等于形参对象 obj,则返回零 ```java package pkg9;
public class CompareTest { public static void main(String[] args) { String str1 = “abc” ; String str2 = “bcd” ; System.out.println(str1.compareTo(str2)); // str1 < str2 应该返回一个负数 } }
<br />这里不能不提一个类:
```java
import java.util.Arrays;
该类中有很多专门用于数组的方法,其中正是因为 compareTo 方法的存在,该类才有很多**静态 sort 方法**对各种数据类型的数组进行升序排序。<br /><br />如下下列代码就调用了 sort 方法来对 String[] 进行了此排序。
package pkg9;
import java.util.Arrays;
public class CompareTest {
public static void main(String[] args) {
String[] strs = new String[]{"AA","CC","MM","BB"} ;
Arrays.sort(strs);
System.out.println(Arrays.toString(strs)); // 用 Arrays 的 toString 方法输出数组
}
}
1.2 自定义类
对于自定义来说,如果想要进行 sort 排序,则必须实现 Comparable 接口,即实现 compareTo 方法,否则无法使用 sort 排序,运行时会报错。
没有实现 Comparable 的类:
package pkg9;
public class Good {
private int price ;
private String name ;
public Good(int price, String name) {
this.price = price;
this.name = name;
}
}
可以看到,对 Good 数组进行 sort 排序,编译并不会报错。但是,在运行时就会出现异常(ClassCastException):
所以自定义类一定要实现 Comparable 接口。然后重写(实现)compareTo(obj) 方法。在方法中自定义比较方式,当当前对象和入参对象怎么怎么样时返回一个正整数,怎么怎么样时返回一个负整数,怎么怎么样时返回一个零。
比如,对上述 Good 类来自定义比较器,如果当前对象价格更高,则返回1,更低则返回-1,相等则返回0:
@Override
public int compareTo(Object o) {
if (o instanceof Good){ // 首先得判断是否为想比较的类
Good o1 = (Good) o;
return Double.compare(this.price,o1.price) ;
}
else {
throw new RuntimeException("传入数据类型不一致") ;
}
}
2. Comparator 比较器接口
Comparator 也是一个比较接口,但是不需要类来实现。在Arrays的 sort 方法中,可以传入两个参数。一个就是要排序的对象数组,另一个就是 Comparator 的匿名实现对象(比较器),在比较器中重写 compare方法就行。
Good 类:
public class Good {
private int price ;
private String name ;
public Good(int price, String name) {
this.price = price;
this.name = name;
}
@Override
public String toString() {
return "Good{" +
"price=" + price +
", name='" + name + '\'' +
'}';
}
public int getPrice() {
return price;
}
public String getName() {
return name;
}
compare 中,如果return > 0 ,sort 就将 o1 排在 o2 后面,如果 return < 0,就将 o2 排在 o1 后面,如果return = 0 ,就不排序。
使用比较器能够非常方便快速的定义排序标准,从名字上就可以看出来,Comparable 指能比较的,所以需要类来实现,以代表改类是可以比较的;而 Comparator 则是个实在的比较器,创建一个匿名实现类的对象即可完成比较。
一般而言,对数组进行排序都是用比较器接口 Comparator 而不是 Comparable 比较器。