Comparable and Comparator

文章详细介绍了Java中的Comparable和Comparator接口的区别。Comparable是实现类的自然排序,需要重写compareTo方法;Comparator则用于外部定制排序,可传递给排序方法如Collections.sort或Arrays.sort。文中通过代码示例展示了如何在Person类中实现这两个接口进行年龄排序。
摘要由CSDN通过智能技术生成

Comparable and Comparator

前言

针对于Comparable和Comparator的区别:

  1. 对于Comparable 而言,该接口是个排序的接口。“对实现它的每个类的对象强加一个整体排序。 这个排序被称为类的自然排序 ,类的compareTo方法被称为其自然比较方法 。” 也就是说comparable的作用是相当于实体类本身添加排序功能。注意需要对于compareTo(Object o)方法进行重写操作。
  2. Comparator :“比较功能,对一些对象的集合施加了一个整体排序 。 可以将比较器传递给排序方法(如Collections.sortArrays.sort ),以便对排序顺序进行精确控制。”也就是说如果该类没有通过实现Comparable接口,那么我们能够建立一个该类的比较器来进行排序的操作。需要注意的是一定要实现重写的compare(T t1,T t2)方法。

Comparable接口

Comparable简介

public interface Comparable<T>{
 // 注意此处的泛型的导入数据的类型
 public int compareTo(T o);
}
  • 该接口实现它的每个类的对象嘉庆一个整体的排序,它的这个排序称之为类的自然排序,类的compareTo方法被称为自然的比较方法。该接口中只有一个方法,就是compareTo().
  • Comparable是java.lang包下面的接口,lang包下面可以看做是java的基础语言接口

代码实现检验

Personpublic class Person implements Comparable<Person>{
    // 注意此处的泛型的操作
    private Integer id;
    private String name;
    private Integer age;

    public Person() {
    }

    public Person(Integer id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }



    @Override
    public int compareTo(Person o) {
        //return this.age - o.age;
        return age - o.age;
    }
}

public class DemoTest {
    @Test
    public void test(){
        /*
         * 对于Comparable的使用经常使用在set集合中,因为set集合中不重复的特性,
         * TreeSet存储的元素是平衡二叉树的存储结构,所以使用的是有序的存储结构,故而需要
         * 对应的类需要实现Comparable接口,进行排序的操作
         */

        TreeSet<Person> set = new TreeSet<>();
        set.add(new Person(1,"王五",33));
        set.add(new Person(2,"张三",43));
        set.add(new Person(3,"李四",23));
        set.add(new Person(4,"周五",31));

        //使用的是方法的引用的操作,将指定的集合进行输出的操作
        set.forEach(System.out::println);

    }
}
运行结果:
    
Person{id=3, name='李四', age=23}
Person{id=4, name='周五', age=31}
Person{id=1, name='王五', age=33}
Person{id=2, name='张三', age=43}

Comparator接口

Comparator简介

  1. Comparator表示的是比较接口,“比较功能,对一些对象的集合施加了一个整体排序 。 可以将比较器传递给排序方法(如Collections.sortArrays.sort ),以便对排序顺序进行精确控制。"
  2. 实现接口,需要进行重写的方法是comparable(T t1,T t2)方法。
  3. 使用的是函数式接口,所以能够通过使用lambda表达式。
核心代码

@FunctionalInterface
interface Comparator<T>{
    int compare(T t1,T t2);
}

代码实现检验


// 代码实现
Personpublic class Person {
    String name;
    int age;
    String address;

    public Person() {
    }

    public Person(String name, int age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }
}


检测实现类:

/**
 * 比较器接口,参数是泛型,用户指定类型
 */
@FunctionalInterface
interface Comparator<T>{

    /**
     * 比较器接口的方法,参数是泛型类型,用户指定类型
     *
     * @param o1    用户在使用接口时约束的泛型对应具体数据类型
     * @param o2    用户在使用接口时约束的泛型对应具体数据类型
     * @return      如果返回0表示的是,两者相同,否则两者不同
     */
    int compare(T o1,T o2);
}



/**
 * @author 法外狂徒张三
 * 2023/3/4
 */
public class Demo {
    public static void main(String[] args) {

        /**
         * 数据的声明赋值部分
         */
        Person[] arr = new Person[5];
        for (int i = 0; i < arr.length; i++) {
            int age = (int) (Math.random()*50);
            arr[i] = new Person("小八嘎",age,"日本");
        }

        /**
         * 匿名内部类比较实现
         */
        comparatorArray(arr, (o1, o2) -> o1.getAge() - o2.getAge());


        /**
         * lambda分析,
         *      首先方法:
         *      int compare(T o1,T o2);
         *      获取泛型之后,泛型的类型是person类型
         *      返回值的数据类型是int类型
         *
         *      方法的参数:2个参数
         *                参数的类型都是Person类型
         *       最终:
         *       (o1,o2) -> {所欲要的最重的返回值}
         */
        comparatorArray(arr, (o1, o2) -> o1.getAge() - o2.getAge());

        for (Person person : arr) {
            System.out.println(person);
        }

    }


    /**
     * 使用的是排序的操作,排序的数组是person 类型,排序的规则使用自定义Comparator 接口实现
     * 接口约束 person 类型
     *
     * @param arr Person类型的数据
     * @param com 针对于Person类型数组的Comparator 比较器接口实现
     */
    public static void comparatorArray(Person[] arr,Comparator<Person> com){

        /**
         * 采用的核心算法是选择排序的算法操作
         */

        for (int i = 0; i < arr.length - 1; i++) {
            int index = i;

            /**
             *   对于比较器中的泛型操作,目前约束的类型是 Person 类型
             *   当前数组中存储的类型就是Person类型对象,可以作为参数,
             *   同时利用compare 方法 返回值返回int类型的数据,作为
             *   排序算法的规则限制。
             */
            for (int j = i + 1; j < arr.length; j++) {
                if (com.compare(arr[index],arr[j] ) > 0 ){
                    index  = j;
                }
            }

            if (index != i) {
                Person temp = arr[index];
                arr[index] = arr[i];
                arr[i] = temp;
            }
        }
    }

}
运行结果:
    
Person{name='小八嘎', age=13, address='日本'}
Person{name='小八嘎', age=18, address='日本'}
Person{name='小八嘎', age=33, address='日本'}
Person{name='小八嘎', age=38, address='日本'}
Person{name='小八嘎', age=45, address='日本'}
/*
 * 进行检测,对于数据进行比较
 */
public class MyComparator {
    public static void main(String[] args) {

        Person[] arr = new Person[5];
        for (int i = 0; i < arr.length; i++) {
            int age = (int) (Math.random()*50);
            arr[i] = new Person("小八嘎",age,"日本");
        }

        // 对于数据进行比较操作
        Arrays.stream(arr).sorted((o1, o2) -> o1.getAge() - o2.getAge()).forEach(System.out::println);

    }
}

运行结果:
Person{name='小八嘎', age=4, address='日本'}
Person{name='小八嘎', age=15, address='日本'}
Person{name='小八嘎', age=16, address='日本'}
Person{name='小八嘎', age=43, address='日本'}
Person{name='小八嘎', age=49, address='日本'}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值