在我们开始比较Comparable和Comparator的异同之前,我们先来看看怎么正确地使用它们。
一、使用Comparable来排序
public class Fruit implements Comparable<Fruit> {
private String name;
private Integer weight;
public Fruit(){}
public Fruit(String name, Integer weight){
this.name = name;
this.weight = weight;
}
@Override
public int compareTo(Fruit o) {
if(this.name.equalsIgnoreCase(o.getName())){
// 相同名称则按照重量降序排列,如果重量也相同则保持添加时的顺序不变
return this.weight <= o.getWeight() ? 1 : -1;
}
return this.name.compareToIgnoreCase(o.getName());
}
// setters and getters...
}
public static void main(String[] args) {
Fruit apple1 = new Fruit("apple",12);
Fruit apple2 = new Fruit("aPple",15);
Fruit apple3 = new Fruit("Apple",9);
Fruit apple4 = new Fruit("appLe",9);
Fruit banana1 = new Fruit("baNana",7);
Fruit banana2 = new Fruit("banAna",7);
Fruit banana3 = new Fruit("Banana",14);
List<Fruit> fruitList = new ArrayList<>();
fruitList.add(banana3);
fruitList.add(apple4);
fruitList.add(apple3);
fruitList.add(banana1);
fruitList.add(apple2);
fruitList.add(banana2);
fruitList.add(apple1);
// 按照水果名称升序排列,如果名称一致则按照重量降序排列
Collections.sort(fruitList);
for(Fruit fruit : fruitList){
System.out.println(fruit.getName() + "-" + fruit.getWeight());
}
}
按照如上代码示例运行结果如下:
aPple-15
apple-12
appLe-9
Apple-9
Banana-14
baNana-7
banAna-7
二、使用Comparator来排序
public class Fruit {
private String name;
private Integer weight;
public Fruit(){}
public Fruit(String name, Integer weight){
this.name = name;
this.weight = weight;
}
// setters and getters...
}
public class FruitComparator implements Comparator<Fruit> {
@Override
public int compare(Fruit o1, Fruit o2) {
if(o1.getName().equalsIgnoreCase(o2.getName())){
// 相同名称则按照重量降序排列,如果重量也相同则保持添加时的顺序不变
return o1.getWeight() <= o2.getWeight() ? 1 : -1;
}
return o1.getName().compareToIgnoreCase(o2.getName());
}
}
public static void main(String[] args) {
Fruit apple1 = new Fruit("apple",12);
Fruit apple2 = new Fruit("aPple",15);
Fruit apple3 = new Fruit("Apple",9);
Fruit apple4 = new Fruit("appLe",9);
Fruit banana1 = new Fruit("baNana",7);
Fruit banana2 = new Fruit("banAna",7);
Fruit banana3 = new Fruit("Banana",14);
List<Fruit> fruitList = new ArrayList<>();
fruitList.add(banana3);
fruitList.add(apple4);
fruitList.add(apple3);
fruitList.add(banana1);
fruitList.add(apple2);
fruitList.add(banana2);
fruitList.add(apple1);
// 按照水果名称升序排列,如果名称一致则按照重量降序排列
fruitList.sort(new FruitComparator());
// Collections.sort(fruitList, new FruitComparator());
for(Fruit fruit : fruitList){
System.out.println(fruit.getName() + "-" + fruit.getWeight());
}
}
按照如上代码示例运行结果如下:
aPple-15
apple-12
appLe-9
Apple-9
Banana-14
baNana-7
banAna-7
三、关于Comparable和Comparator的异同
相同点
- 在功能上两者能实现完全一样的排序需求;
- 在两者都可使用的情况下,随意使用一个即可;
不同点
- Comparable需要主体自己实现接口并重写compareTo方法;
- Comparable只能使用Collections.sort方法进行排序;
- Comparator需要单独创建一种排序策略,在排序的时候指定使用;
- Comparator既可以使用Collections.sort也可以使用list.sort方法;
四、使用总结
- 当排序主体本身实现了Comparable接口,且其重写的排序策略符合需求的时候,直接使用Comparable的排序方案即可;
- 当排序主体虽然实现了Comparable接口,但是其本身重写的排序策略不能满足需求,则需要使用Comparator,新建一种排序策略;
- 当排序主体没有实现Comparable接口的时候,可以考虑让其实现Comparable接口并重写排序策略,也可以使用Comparator单独新建一种排序策略;
- Comparable需要对排序主体进行修改,侵入性较高,而Comparator无需更改任何排序主体的代码,体现了策略模式的思想,在排序场景较多的情况下较为推荐。
网友评论