Java中的Comparable与Comparator
Comparable和Comparator都是用来实现集合中元素的比较、排序的。Comparable是在集合内部定义的方法实现的排序;而Comparator是在集合外部实现的排序。
Comparable是一个对象本身就已经支持自比较所需要实现的接口,如String、Integer就实现了Comparable接口,可完成比较大小操作。自定义类实现该接口后,其对应集合或数组就能够直接使用Collections类的sort方法或者Arrays类的sort方法进行排序。当然如果自定义类没有实现Comparable接口,但是又希望使用sort方法对集合或数组中的该类对象进行排序,那么就可以指定比较器来进行排序。通过实现Comparable接口来实现排序的方式又叫自然顺序排序。
Comparator是一个专用的比较器,当这个对象不支持自比较或者自比较函数不能满足要求时,可写一个比较器来完成两个对象之间大小的比较。Comparator体现了一种策略模式(strategy design pattern),就是不改变对象自身,而用一个策略对象(strategy object)来改变它的行为。
Comparable接口
public interface Comparable<T> {
public int compareTo(T o);
}
Comparator接口public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
}
Comparable实例
package hdd.com;
import java.util.Arrays;
class Rectangle implements Comparable<Rectangle>{
private int weight;
private int height;
public Rectangle() {
this(0, 0);
}
public Rectangle(int weight, int height){
this.weight = weight;
this.height = height;
}
public int getWeight(){
return weight;
}
public int getHeight(){
return height;
}
public int getArea(){
return this.weight * this.height;
}
@Override
public int compareTo(Rectangle rect) {
if(this.weight * this.height < rect.weight * rect.height){
return -1;
}else if(this.weight * this.height == rect.weight * rect.height){
return 0;
}else{
return 1;
}
}
}
public class Test {
public static void main(String[] args){
Rectangle rects[] = new Rectangle[5];
rects[0] = new Rectangle(4, 6);
rects[1] = new Rectangle(5, 5);
rects[2] = new Rectangle(3, 7);
rects[3] = new Rectangle(6, 2);
rects[4] = new Rectangle(4, 4);
Arrays.sort(rects);
for(int i = 0; i < rects.length; i++){
System.out.print(rects[i].getArea() + " ");
}
}
}
运行结果:
12 16 21 24 25
package hdd.com;
import java.util.Arrays;
import java.util.Comparator;
class Rectangle{
private int weight;
private int height;
public Rectangle() {
this(0, 0);
}
public Rectangle(int weight, int height){
this.weight = weight;
this.height = height;
}
public int getWeight(){
return weight;
}
public int getHeight(){
return height;
}
public int getArea(){
return this.weight * this.height;
}
}
class DefineComparator implements Comparator<Rectangle>{
@Override
public int compare(Rectangle rect1, Rectangle rect2) {
if(rect1.getWeight() * rect1.getHeight() < rect2.getWeight() * rect2.getHeight()){
return -1;
}else if(rect1.getWeight() * rect1.getHeight() == rect2.getWeight() * rect2.getHeight()){
return 0;
}else{
return 1;
}
}
}
public class Test {
public static void main(String[] args){
Rectangle rects[] = new Rectangle[5];
rects[0] = new Rectangle(4, 6);
rects[1] = new Rectangle(5, 5);
rects[2] = new Rectangle(3, 7);
rects[3] = new Rectangle(6, 2);
rects[4] = new Rectangle(4, 4);
Arrays.parallelSort(rects, new DefineComparator());
for(int i = 0; i < rects.length; i++){
System.out.print(rects[i].getArea() + " ");
}
}
}
运行结果:12 16 21 24 25
有些人会感到疑惑,Comparator接口中有两个抽象方法(equals与compare),而实现类DefineComparator中只实现了compare方法,那么为什么类DefineComparator还能够创建对象。我理解的是当DefineComparator实现接口Comparator接口时,同时隐式的继承了父类Object,也就继承了Object类中的equals方法,类DefineComparator并不是一个抽象类,所以它可以创建对象。