案例解释-实现Comparator接口为什么不用实现Equals方法

0.实验准备
0.1一个标准类

public class Person {
    private String name;
    private int age;

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

    public Person() {
    }

    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;
    }
}

0.2一个测试类,创建TreeSet对象并存入几个person对象

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

public class test9 {
    public static void main(String[] args) {
        Person p1=new Person("cao",40);
        Person p2=new Person("bei",30);
        Person p3=new Person("yu",20);
        Person p4=new Person("aei",20);

        Set<Person> ps=new TreeSet<>();
        ps.add(p1);
        ps.add(p2);
        ps.add(p3);
        ps.add(p4);

        for (Person p : ps) {
            System.out.println(p);
        }
    }
}

0.3运行结果

Exception in thread "main" java.lang.ClassCastException:
 class com.test9.Person cannot be cast to class java.lang.
 Comparable (com.test9.Person is in unnamed module of loader 'app'; java.lang.Comparable is in module java.base of loader 'bootstrap')

0.4原因分析
TreeSet集合存取顺序是不一致的,但取数据的时候有一定的规则,基本数据类型有默认规则,读者可以将存入数据换成整形去实验一下。但是存入自定义的整形数据类型时则报错Person cannot be cast to class java.lang.Comparable。
1.改进规则问题引入
那么我们就手动写一个规则进去。发现TreeSet有参构造且参数是一个接口,我们先采取匿名内部类的方式实现,发现只重写了一个方法。comparaTo方法 根据返回值排序。
Result<0放左边 result>0放右边 =0不存o.变量是已经存的,this.变量正在存的String也继承了自然排序TreeSet不依赖.equals方法。
:里面的规则非本文章重点

Comparator<? super E> comparator

在这里插入图片描述

 Set<Person> ps=new TreeSet<>(new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                //o1为当前要存储的对象 o2集合中的对象
                int result=o1.getAge()-o2.getAge();
                result=result==0?o1.getName().compareTo(o2.getName()):result;
                return result;
            }
        });

1.1引入
既然只重写了接口中的一个方法,那么就是说接口中只有一个抽象方法呗,那么lambda表达式当然也是管用的。

 //lambda实现
        Set<Person> ps=new TreeSet<>((o1,o2)->{
            //o1为当前要存储的对象 o2集合中的对象
            int result=o2.getAge()-o1.getAge();
            result=result==0?o2.getName().compareTo(o1.getName()):result;
            return result;
        });

1.2我们现在看看Comparator接口的所有方法,这就很奇怪了,为什么有俩抽象方法呢?那我不是应该重写俩方法才对吗?
在这里插入图片描述
在这里插入图片描述
1.3这就要说起java的祖宗Object了,Object是所有java类的父类,定义了一些方法,其中就有equals方法,让我们来看一下。果然在哈,那为什么不用重写呢?因为父类已经有该方法且是具体的方法。
在这里插入图片描述
1.4举个栗子
定义Animal接口

//相当于比较器
public interface Animal {
    void eat();
}
//假如这个是超类Object
public class Cat {
    //假如这个就是equals
    public void eat(){
        System.out.println("喜欢吃鱼");
    }
}

测试–不报错

public class Test extends Cat implements Animal {

}
class TTest {
    public static void main(String[] args) {
        Animal animal=new Test();
        animal.eat();
    }
}
//喜欢吃鱼

1.5总结
如果一个类既有继承又有实现。并且接口中的方法与父类接口中的方法相同,那么该类不用重写接口中的方法也可以。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值