Java Comparable与Comparator区别

1,两种接口的展示

下面的程序是两个类各自实现了Comparable接口、Comparator接口

package com.cnblogs.mufasa.Solution;

import java.util.Comparator;

class Solution1 implements Comparable<Solution1>{
    int val;
    public Solution1(int val){
        this.val=val;
    }

    @Override
    public int compareTo(Solution1 o) {
        return val-o.val;
    }
}

class Solution2 implements Comparator<Solution2> {
    int val;
    public Solution2(int val){
        this.val=val;
    }

    @Override
    public int compare(Solution2 o1, Solution2 o2) {
        return o1.val-o2.val;
    }
}

public class Client{
    public static void main(String[] args) {
        Solution1 sl1=new Solution1(5);
        Solution1 sl2=new Solution1(1);
        System.out.println("sl1.compareTo(sl2):"+sl1.compareTo(sl2));

        Solution2 sl21=new Solution2(5);
        Solution2 sl22=new Solution2(1);
        System.out.println("sl21.compare(sl21,sl22):"+sl21.compare(sl21,sl22));
        System.out.println("sl21.compare(sl21,sl22):"+sl21.reversed().compare(sl21,sl22));
    }
}
/*
sl1.compareTo(sl2):4
sl21.compare(sl21,sl22):4
sl21.compare(sl21,sl22):-4
 */

2,两种接口的比较

  通过上面的展示程序,我们可以发现这两个接口实现起来都很简单,并且实现的逻辑都基本一样。但是差别还是有的!

   上面是我总结的一些各自的相同点与不同点。

3,各自优缺点

  Comparable实现简单、功能纯粹单一;Comparator实现可简单可复杂,可以在进行Collections.sort()以及Arrays.sort()中临时实现这个接口,并且实现方式还花里胡哨的【函数式编程、直接比较等等】

package com.cnblogs.mufasa.Solution2;

import java.util.Arrays;
import java.util.Comparator;

public class Person implements Comparable<Person> {
    private String name;
    private int age;
    public Person(String name,int age){
        this.name=name;
        this.age=age;
    }

    @Override
    public int compareTo(Person o) {//先按照姓名的字典序排序,再按照年龄的由小到大排序
        String ab=name+o.name;
        String ba=o.name+name;
        int len=ab.length();
        for(int i=0;i<len;i++){
            int temp=ab.charAt(i)-'0'-ba.charAt(i);
            if(temp<0){
                return -1;
            }else if(temp>0){
                return 1;
            }
        }
        return age-o.age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

class Client{
    public static void main(String[] args) {
        Person[] ps=new Person[6];
        ps[0]=new Person("Mufasa",22);
        ps[1]=new Person("Mufasa",18);
        ps[2]=new Person("Wanyu",24);
        ps[3]=new Person("Guoyahong",24);
        ps[4]=new Person("Guoyahong",26);
        ps[5]=new Person("Admin",26);

        for(Person p:ps){
            System.out.print(p.getName()+","+p.getAge()+"	");
        }
        System.out.println();

//        Arrays.sort(ps);//使用自带的Comparable可以直接实现
//        Arrays.sort(ps,Comparator.comparing(Person::getName).thenComparing(Person::getAge));//使用Comparator验证成功
//        Arrays.sort(ps,Comparator.comparing(Person::getName).thenComparing(Person::getAge).reversed());//使用Comparator进行反转reversed,整体反转
//        Arrays.sort(ps,Comparator.comparing(Person::getName).reversed().thenComparing(Person::getAge));//使用Comparator进行反转reversed,部分反转1
        Arrays.sort(ps,Comparator.comparing(Person::getName).reversed().thenComparing(Person::getAge).reversed());//使用Comparator进行反转reversed,部分反转2

//        Arrays.sort(ps,(a,b)->{//利用Comparator接口的简化函数式编程,平时我使用的就是这个简单易用
//            String ab=a.getName()+b.getName();
//            String ba=b.getName()+a.getName();
//            int len=ab.length();
//            for(int i=0;i<len;i++){
//                int temp=ab.charAt(i)-'0'-ba.charAt(i);
//                if(temp<0){
//                    return -1;
//                }else if(temp>0){
//                    return 1;
//                }
//            }
//            return a.getAge()-b.getAge();
//        });

        for(Person p:ps){
            System.out.print(p.getName()+","+p.getAge()+"	");
        }
        System.out.println();
    }
}

4,应用领域

  一般情况下,我们默认使用Comparable接口【优先选择】,主要是因为这种比较方法简单易实现,并且功能纯粹;

  如果Comparable实现的比较功能,我们自己不满意想要临时更改,那么花里胡哨的Comparator就闪亮登场了,这个功能多,并且低耦合度,我们可以使用的时候随意进行调整,并且还可以【把多个Comparator链在一起】去实现更加复杂的比较逻辑!

list.sort(Comparator.comparing(Employee::getSalary).thenComparing(Employee::getName));//多个Comparator链接组合成复杂排序-层级排序

5,参考链接

https://www.cnblogs.com/szlbm/p/5504634.html

https://blog.csdn.net/bitcarmanlee/article/details/73381705

原文地址:https://www.cnblogs.com/Mufasa/p/11430353.html