Comparable与Comparator的具体应用场景

在项目开发中,我们经常要对一组数据进行排序,或者升序或者降序,在Java中排序有多种方式,最土的方式就是自己写排序算法,比如冒泡排序、快速排序、二叉树排序等,但一般不需要自己写,JDK已经为我们提供了很多的排序算法,我们采用”拿来主义” 就成了。在Java中,要想给数据排序,有两种实现方式,一种是实现Comparable接口,一种是实现Comparator接口,这两者有什么区别呢?我们来看一个例子,就比如给公司职员按照工号排序吧,先定义一个职员类代码,如下所示:
  1. public class Employee implements Comparable<Employee>{  
  2.     private int id;  
  3.     private String name;  
  4.     private Position position;  
  5.     public Employee(int id,String name,Position position){  
  6.         this.id = id;  
  7.         this.name = name;  
  8.         this.position = position;  
  9.     }  
  10.   
  11.     public int getId() {  
  12.         return id;  
  13.     }  
  14.   
  15.     public void setId(int id) {  
  16.         this.id = id;  
  17.     }  
  18.   
  19.     public String getName() {  
  20.         return name;  
  21.     }  
  22.   
  23.     public void setName(String name) {  
  24.         this.name = name;  
  25.     }  
  26.   
  27.     public Position getPosition() {  
  28.         return position;  
  29.     }  
  30.   
  31.     public void setPosition(Position position) {  
  32.         this.position = position;  
  33.     }  
  34.      //我是按照Id升序排列  
  35.     @Override  
  36.     public int compareTo(Employee o) {  
  37.         if(this.id > o.id){  
  38.             return 1;  
  39.         }else if(this.id < o.id){  
  40.             return -1;  
  41.         }else  
  42.             return 0;  
  43.     }  
  44.     public String toString(){  
  45.         return “编号:” + this.id + “姓名:” + this.name + “职位:” + this.position;  
  46.     }  
  47.     enum Position{  
  48.         Boss,Manager,Staff  
  49.     }  
  50.       
  51. }  
public class Employee implements Comparable<Employee>{
    private int id;
    private String name;
    private Position position;
    public Employee(int id,String name,Position position){
        this.id = id;
        this.name = name;
        this.position = position;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Position getPosition() {
        return position;
    }

    public void setPosition(Position position) {
        this.position = position;
    }
     //我是按照Id升序排列
    @Override
    public int compareTo(Employee o) {
        if(this.id > o.id){
            return 1;
        }else if(this.id < o.id){
            return -1;
        }else
            return 0;
    }
    public String toString(){
        return "编号:" + this.id + "姓名:" + this.name + "职位:" + this.position;
    }
    enum Position{
        Boss,Manager,Staff
    }

}

编写客户端程序进行测试:

  1. public class Client {  
  2.     public static void main(String[] args){  
  3.         List<Employee> list = new ArrayList<>(5);  
  4.         list.add(new Employee(1004,“sd”,Employee.Position.Staff));  
  5.         list.add(new Employee(1005,“sa”, Employee.Position.Staff));  
  6.         list.add(new Employee(1002,“ls”, Employee.Position.Manager)) ;  
  7.         list.add(new Employee(1003,“ww”, Employee.Position.Manager));  
  8.         list.add(new Employee(1001,“zs”, Employee.Position.Boss));  
  9.         System.out.println(List.class);  
  10.         //按照id升序排列,如果想按照名字升序排列就要用到Comparator  
  11.         Collections.sort(list);  
  12.         for(Employee e:list){  
  13.             System.out.println(e);  
  14.         }  
  15.     }  
  16. }  
public class Client {
    public static void main(String[] args){
        List<Employee> list = new ArrayList<>(5);
        list.add(new Employee(1004,"sd",Employee.Position.Staff));
        list.add(new Employee(1005,"sa", Employee.Position.Staff));
        list.add(new Employee(1002,"ls", Employee.Position.Manager)) ;
        list.add(new Employee(1003,"ww", Employee.Position.Manager));
        list.add(new Employee(1001,"zs", Employee.Position.Boss));
        System.out.println(List.class);
        //按照id升序排列,如果想按照名字升序排列就要用到Comparator
        Collections.sort(list);
        for(Employee e:list){
            System.out.println(e);
        }
    }
}
这里只是依据id进行的排序,这就是Employee默认的排序算法, 但是,有时候我们希望按照职位来排序,职位一样的话我在根据id排序那怎么做呢?此时,重构Employee类已经不合适了,Employee已经是一个稳定类,为了排序功能修改它不是一个好办法,哪有什么好的解决办法吗?

有办法,看Collections.sort方法,它有一个重载方法Collections.sort(List<T>  list, Comparator<? super T> c),可以接收一个Comparator实现类,这下就好办了,在Employee类中增加一段代码即可代码如下:

  1. static class PositionComparator implements Comparator<Employee>{  
  2.   
  3.         @Override  
  4.         public int compare(Employee o1, Employee o2) {  
  5.             int len1 = o1.getPosition().toString().length();  
  6.             int len2 = o2.getPosition().toString().length();  
  7.             //找到他们两个长度的最小值  
  8.             int minLen = Math.min(len1,len2);  
  9.             char[] v1 = o1.getPosition().toString().toCharArray();  
  10.             char[] v2 = o2.getPosition().toString().toCharArray();  
  11.             int k = 0;  
  12.             while(k < minLen){  
  13.                 char vp = v1[k];  
  14.                 char vl = v2[k];  
  15.                 if(vp != vl){  
  16.                    return vl - vp;  
  17.                 }else{  
  18.                     break;  
  19.                 }  
  20.   
  21.             }  
  22.             //如果职位相同再按照工号排序  
  23.                 if(o1.getId() > o2.getId()){  
  24.                     return -1;  
  25.                 }else if(o1.getId() < o2.getId()){  
  26.                     return 1;  
  27.                 }else  
  28.                     return 0;  
  29.             }  
  30.   
  31.     }  
static class PositionComparator implements Comparator<Employee>{

        @Override
        public int compare(Employee o1, Employee o2) {
            int len1 = o1.getPosition().toString().length();
            int len2 = o2.getPosition().toString().length();
            //找到他们两个长度的最小值
            int minLen = Math.min(len1,len2);
            char[] v1 = o1.getPosition().toString().toCharArray();
            char[] v2 = o2.getPosition().toString().toCharArray();
            int k = 0;
            while(k < minLen){
                char vp = v1[k];
                char vl = v2[k];
                if(vp != vl){
                   return vl - vp;
                }else{
                    break;
                }

            }
            //如果职位相同再按照工号排序
                if(o1.getId() > o2.getId()){
                    return -1;
                }else if(o1.getId() < o2.getId()){
                    return 1;
                }else
                    return 0;
            }

    }
如果想改变排序方式在compare方法中改变vl,vp的位置就可以办到了
!!!Comparable接口可以作为实现类的默认排序算法,Comparator接口则是一个类的扩展排序工具

参考原文:参考文章

 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值