前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >java进阶|比较器Comparable和Comparator

java进阶|比较器Comparable和Comparator

作者头像
码农王同学
发布2020-07-06 09:51:23
6910
发布2020-07-06 09:51:23
举报
文章被收录于专栏:后端Coder

一,可能对于java的coder来说,这个点很简单,但对于我来说又是很难,想写这篇文章也是很久了,今天就以自己的理解来看下这两个接口,首先我们先看下Comparable接口的结构图。

这个比较接口只包含了一个compareTo()方法的接口,Comparable是一个排序接口,当我们定义的类实现了该接口,就说明了该类支持排序。

代码语言:javascript
复制
我们通过x.compareTo(y)来比较x和y的大小。若返回负数,则x比y小,若返回0,则x=y,若返回整数,则x大于y。

二,这里,自己去编写一个静态内部类来进行测试Comparable接口的使用。

代码语言:javascript
复制
package com.wpw.springbootjuc.java8.map;

import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;

import java.util.Collections;
import java.util.List;

/**
 * Comparable接口
 *
 * @author wpw
 */
@Slf4j
public class ComparableTest {
    public static void main(String[] args) {
        List<Person> personList = Lists.newArrayList();
        getPersonList(personList);
        System.out.println("Before Sort");
        acceptAndPrint(personList);
        Collections.sort(personList);
        System.out.println("After Sort");
        acceptAndPrint(personList);

    }

    private static void acceptAndPrint(List<Person> personList) {
        personList.stream().forEach(x -> {
            System.out.println(String.format("Id:%d,Name:%s,Age:%d", x.getId(), x.getName(), x.getAge()));
        });
        System.out.println();
    }

    /**
     * @return 数据集合,这里就简单模拟一下
     */
    private static void getPersonList(List<Person> personList) {
        personList.add(Person.builder().build().setId(3).setName("John").setAge(18));
        personList.add(Person.builder().build().setId(1).setName("Tom").setAge(20));
        personList.add(Person.builder().build().setId(2).setName("Marry").setAge(21));
    }


}

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Accessors(chain = true)
class Person implements Comparable<Person> {
    private Integer id;
    private String name;
    private Integer age;

    /**
     * @param o 待比较的对象
     * @return 比较的值-1,0,1
     */
    @Override
    public int compareTo(Person o) {
        return this.id - o.id;
    }
}

排序前后输出的结果信息:

代码语言:javascript
复制
Before Sort
Id:3,Name:John,Age:18
Id:1,Name:Tom,Age:20
Id:2,Name:Marry,Age:21

After Sort
Id:1,Name:Tom,Age:20
Id:2,Name:Marry,Age:21
Id:3,Name:John,Age:18

三,接下来看下Comparator接口的结构图,这就是一个函数式接口,函数式接口就是只有一个方法,但是它可以有其它的默认方法。

四,下面的这张图就是Comparator接口包含的所有方法,大部分的都是default方法。

这里编写了一个示例程序用于测试Comparator接口的使用,Comparator为比较器接口,若要实现某个本身不支持排序的类,可以通过定义一个Comparator接口来实现类的排序。

代码语言:javascript
复制
package com.wpw.springbootjuc.java8.map;

import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * Comparator接口
 *
 * @author wpw
 */
public class ComparatorTest {
    public static void main(String[] args) {
        List<Student> studentList = Lists.newArrayList();
        getStudentList(studentList);
        System.out.println("Before Sort");
        acceptAndPrint(studentList);
        Collections.sort(studentList, new MyComparator());
        System.out.println("After Sort");
        acceptAndPrint(studentList);
    }

    private static void acceptAndPrint(List<Student> studentList) {
        studentList.stream().forEach(x -> {
            System.out.println(String.format("Id:%d,Name:%s,Age:%d", x.getId(), x.getName(), x.getAge()));
        });
        System.out.println();
    }

    /**
     * @return 数据集合,这里就简单模拟一下
     */
    private static void getStudentList(List<Student> studentList) {
        studentList.add(Student.builder().build().setId(3).setName("John").setAge(18));
        studentList.add(Student.builder().build().setId(1).setName("Tom").setAge(20));
        studentList.add(Student.builder().build().setId(2).setName("Marry").setAge(21));
    }

    @AllArgsConstructor
    @NoArgsConstructor
    @Data
    @Builder
    @Accessors(chain = true)
    static class Student {
        private Integer id;
        private String name;
        private Integer age;
    }

    /**
     * 自定义比较器接口
     */
    static class MyComparator implements Comparator<Student> {

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

        @Override
        public boolean equals(Object obj) {
            return super.equals(obj);
        }
    }
}

五,以上就是Comparable和Comparator接口都是用来实现集合中元素的比较和排序的,当我们自己定义的一个类需要进行排序时,就要考虑实现Comparable或者Comparator接口,这样就可以根据指定的属性进行排序。

六,何时使用Comparable接口,何时使用Comparator接口?当我们在对要排序的排序规则比较固定,则考虑使用Comparable接口,若要对排序的类的排序规则是经常变化的,那我们就考虑使用Comparator接口。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农王同学 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档