如何实现Comparable、Comparator接口

针对Java中对象数组排序问题,Java中提供两种实现方式。

  1. 实现Comparable接口方式(自然排序);
  2. 实现Comparator接口方式(定制排序);

1. 自然排序和定制排序的异同点:

自然排序:需要进行排序的类实现Comparable接口,并且重写compareTo方法,compareTo方法只有一个参数,。
定制排序:需要在需要排序的类之外再定义一个类实现Comparator接口,并且重写compare方法,compare方法有两个参数。
相同点:compareTo和compare方法返回值都是int类型,并且方法内部比较的两个对象,大于返回正数,小于则返回负数,如果相等则返回0.

2. 实现代码:

自然排序实例:
学生实体类:

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student implements Comparable<Student>{

   private String studentName;
   private int score;


   @Override
   public int compareTo(Student o) {
       //根据学生分数进行增序排序,在两个学生分数相同情况下,根据学生姓名进行升序排序
       if(this.score > o.score){
           return 1;
       }else if (this.score < o.score){
           return -1;
       }else {
           return this.studentName.compareTo(o.studentName);
       }
   }
}

测试方法:

@Test
public void test01(){
    Student[] students = new Student[5];
    students[0] = new Student("王二",84);
    students[1] = new Student("张三",89);
    students[2] = new Student("李四",60);
    students[3] = new Student("王五",93);
    students[4] = new Student("赵六",84);
    Arrays.sort(students);
    System.out.println(Arrays.toString(students));
}

测试结果:

[Student(studentName=李四, score=60), Student(studentName=王二, score=84), Student(studentName=赵六, score=84), Student(studentName=张三, score=89), Student(studentName=王五, score=93)]

定制排序实例:
定制排序比较器:

public class StudentComparator implements Comparator<Student>{
    @Override
    public int compare(Student o1, Student o2) {
    	//根据学生分数,进行降序排列,如果学生分数相等根据人员姓名进行降序排列。
        if(o1.getScore() > o2.getScore()){
            return -1;
        }else if (o1.getScore() < o2.getScore()){
            return 1;
        }else {
            return -o1.getStudentName().compareTo(o2.getStudentName());
        }
    }
}

测试方法:

 @Test
 public void test02(){
      Student[] students = new Student[5];
      students[0] = new Student("王二",84);
      students[1] = new Student("张三",89);
      students[2] = new Student("李四",60);
      students[3] = new Student("王五",93);
      students[4] = new Student("赵六",84);
      Arrays.sort(students,new StudentComparator());
      System.out.println(Arrays.toString(students));
 }

测试结果:

[Student(studentName=王五, score=93), Student(studentName=张三, score=89), Student(studentName=赵六, score=84), Student(studentName=王二, score=84), Student(studentName=李四, score=60)]

对于定制排序需要另外定义一个类作为比较器,我们可以使用匿名实现类,从而不需要再另外定义一个类。所以定制排序的另一种写法如下代码显示(也可以简化使用lambda表达式):

@Test
    public void test03(){
        Student[] students = new Student[5];
        students[0] = new Student("王二",84);
        students[1] = new Student("张三",89);
        students[2] = new Student("李四",60);
        students[3] = new Student("王五",93);
        students[4] = new Student("赵六",84);
        Arrays.sort(students, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                if(o1.getScore() > o2.getScore()){
                    return -1;
                }else if (o1.getScore() < o2.getScore()){
                    return 1;
                }else {
                    return -o1.getStudentName().compareTo(o2.getStudentName());
                }
            }
        });
        System.out.println(Arrays.toString(students));
    }

集合中使用到的自然排序和定制排序:
Collections.sort(List< T> list);(可实现自然排序);
Collections.sort(List< T> list,Comparator<? super Object> c);
TreeMap中自然排序:

@Test
    public void test06(){
        TreeMap<Student,Integer> treeMap = new TreeMap<>();
        treeMap.put(new Student("王二",84),49);
        treeMap.put(new Student("张三",89),54);
        treeMap.put(new Student("李四",60),44);
        treeMap.put(new Student("王五",93),62);
        treeMap.put(new Student("赵六",84),21);
        Iterator<Map.Entry<Student, Integer>> iterator = treeMap.entrySet().iterator();
        while (iterator.hasNext()){
            Map.Entry<Student,Integer> map = iterator.next();
            System.out.println(map.getKey() + "------->" + map.getValue());
        }
    }

测试结果:

Student(studentName=李四, score=60)------->44
Student(studentName=王二, score=84)------->49
Student(studentName=赵六, score=84)------->21
Student(studentName=张三, score=89)------->54
Student(studentName=王五, score=93)------->62

TreeMap中定制排序:

@Test
    public void test07(){
        TreeMap<Student,Integer> treeMap = new TreeMap<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                if(o1.getScore() > o2.getScore()){
                    return -1;
                }else if (o1.getScore() < o2.getScore()){
                    return 1;
                }else {
                    return o1.getStudentName().compareTo(o2.getStudentName());
                }
            }
        });
        treeMap.put(new Student("王二",84),49);
        treeMap.put(new Student("张三",89),54);
        treeMap.put(new Student("李四",60),44);
        treeMap.put(new Student("王五",93),62);
        treeMap.put(new Student("赵六",84),21);
        Iterator<Map.Entry<Student, Integer>> iterator = treeMap.entrySet().iterator();
        while (iterator.hasNext()){
            Map.Entry<Student,Integer> map = iterator.next();
            System.out.println(map.getKey() + "------->" + map.getValue());
        }
    }

测试结果:

Student(studentName=王五, score=93)------->62
Student(studentName=张三, score=89)------->54
Student(studentName=王二, score=84)------->49
Student(studentName=赵六, score=84)------->21
Student(studentName=李四, score=60)------->44

3. 优缺点:

自然排序实现Comparable接口比较简单,不需要另外定义一个比较器类,但要修改进行比较类的原有代码。定制排序实现Comparator接口需要另外定义一个类,作为比较器,比较复杂,但实现不需要对原代码修改,只需要另外定义比较规则的类即可。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值