美文网首页
Java中的Comparable和Comparator

Java中的Comparable和Comparator

作者: 文景大大 | 来源:发表于2019-05-13 15:43 被阅读0次

在我们开始比较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无需更改任何排序主体的代码,体现了策略模式的思想,在排序场景较多的情况下较为推荐。

相关文章

网友评论

      本文标题:Java中的Comparable和Comparator

      本文链接:https://www.haomeiwen.com/subject/keglaqtx.html