• 对象的比较(下)


    作者~小明学编程  

    文章专栏Java数据结构

    格言目之所及皆为回忆,心之所想皆为过往

    目录

    比较器的比较

    equals的比较

    三种方式的比较


    比较器的比较

    1. class Card {
    2. public int rank; // 数值
    3. public String suit; // 花色
    4. public Card(int rank, String suit) {
    5. this.rank = rank;
    6. this.suit = suit;
    7. }
    8. @Override
    9. public String toString() {
    10. return "Card{" +
    11. "rank=" + rank +
    12. ", suit='" + suit + '\'' +
    13. '}';
    14. }
    15. }
    16. class RankComparator implements Comparator {
    17. @Override
    18. public int compare(Card o1,Card o2) {
    19. return o1.rank - o2.rank;
    20. }
    21. }
    22. public class Test {
    23. public static void main(String[] args) {
    24. Card card1 = new Card(2,"♠");
    25. Card card2 = new Card(3,"♠");
    26. RankComparator rankComparator = new RankComparator();
    27. rankComparator.compare(card1,card2);
    28. }
    29. }

    比较器的用法就如上述的代码所示,我们首先构造一个类然后实现我们的Comparator的接口,接着就是重写我们里面的compare方法,然后就可以用它进行比较了。

    当然我们在使用优先级队列的时候可以直接向里面传入我们的比较器。

    1. public static void main(String[] args) {
    2. //默认是一个小堆
    3. RankComparator rankComparator = new RankComparator();
    4. PriorityQueue priorityQueue = new PriorityQueue<>(rankComparator);
    5. }

    当然这样写可能会觉得麻烦,因为我们首先要写一个类,然后还要我们的类来实现接口然后重写方法,那么有没有简单点的写法呢?

    1. public static void main(String[] args) {
    2. //默认是一个小堆
    3. PriorityQueue priorityQueue2 = new PriorityQueue<>(new Comparator() {
    4. @Override
    5. public int compare(Card o1, Card o2) {
    6. return o1.rank - o2.rank;
    7. }
    8. });
    9. }

    我们可以运用内部类的写法,就是在我们new一个接口的时候就直接重写我们的compare方法。

    1. PriorityQueue priorityQueue1 = new PriorityQueue<>((x,y)-> {
    2. return x.rank - y.rank;
    3. });

    当然,还有更加简单的写法,lambda的写法,不过这种写法过于的抽象不建议用。

    equals的比较

    1. public static void main(String[] args) {
    2. Card card1 = new Card(3,"♠");
    3. Card card2 = new Card(3,"♠");
    4. System.out.println(card1.equals(card2));
    5. }

    结果意料之外情理之中,咋一看我们的两个对象的数字和花色都一样,但是为什么会返回一个false呢?我们点开源码看一下就知道了。

    1. public boolean equals(Object obj) {
    2. return (this == obj);
    3. }

    这里equals比较的是一个地址,我们两个对象的地址不一样所以就是false,这时候我们重写一下我们的equals()方法。

    1. @Override
    2. public boolean equals(Object o) {
    3. if (this == o) return true;
    4. if (o == null || getClass() != o.getClass()) return false;
    5. Card card = (Card) o;
    6. return rank == card.rank && Objects.equals(suit, card.suit);
    7. }

    简单解析一下源码,首先是比较我们的地址地址一样的话,那么直接返回true,接着就是判断类型,类型不一样直接返回false,最后就是判断花色和数字,返回我们能的结果。

    三种方式的比较

    覆写的方法说明
    Object.equals因为所有类都是继承自 Object 的,所以直接覆写即可,不过只能比较相等与
    Comparable.compareTo需要手动实现接口,侵入性比较强,但一旦实现,每次用该类都有顺序,属于
    内部顺序
    Comparator.compare需要实现一个比较器对象,对待比较类的侵入性弱,但对算法代码实现侵入性

  • 相关阅读:
    【操作系统】9/35MMAP
    Linux常见的链接命令有几种?分别是什么?
    uva 10366 - Faucet Flow(贪心)
    【Harmony OS】【ARK UI】组件内转场api 基本使用
    微软数据库的SQL注入漏洞解析——Microsoft Access、SQLServer与SQL注入防御
    mybatis防注入
    离散卡尔曼滤波器算法详解及重要参数(Q、R、P)的讨论
    Ubuntu16.04 完整版 Gym 安装及说明
    在Vue.js中,什么是组件通信?有哪些方法可以实现组件通信?
    【2023高教社杯数学建模国赛】ABCD题 问题分析、模型建立、参考文献及实现代码
  • 原文地址:https://blog.csdn.net/m0_56911284/article/details/127813603