• Java 比较(==, equals, compareTo, compare)


    在Java中,有 ==, equals(), compareTo(), compare() 等方法可以比较两个值或对象,比较容易混淆。画了个简单的思维导图总结一下

    Paste_Image.png

    Java Compares

    我经常记不住Java中的各种比较方法,为什么设计者要弄出这么多种比较?

    设计源于生活,如果我们先想一想现实世界中一般会如何做比较,也许会对理解Java的设计有所帮助吧。那么,在现实世界中,我们是怎么进行比较的呢?

    假如给定两个物体,如果要对二者作比较的话,一般我们会先问:

    有可比性吗?

    如果没有可比性,那就无需再谈。但是从广义上讲,其实任何东西都可以互相比较的,所以可比性是有个限定范围的,即如果要两者可比,那就得限定规则范围,这样也就可以理解 Java 中 compareTo 了:

    **在 Java 中 compareTo() 可以比较的两个对象的类必须都实现 Comparable 接口。

    compare() 则是 Comparator 接口定义的方法。**

    如果有可比性,又会问:

    为什么比?
    比啥?
    怎么比?

    让我们挨个来看:

    为什么比?
    因为要根据比较的结果来做决策或决定,具体就不展开了,各种应用情况不一样。比如:公司的绩效考核评优,运动会比赛夺冠等等。

    **在 Java 中 equals()的比较结果是 boolean 类型,如果是 true 则表示二者相同的时候do something, 否则不同的时候 do else things,

    而compareTo() ,compare() 的比较结果是:0表示相同,正负数表示不同,至于是正负多少,看所不同的字符在编码表中的差距。至于为啥要这么设计,我初步的想法是,根据不同的返回值的大小,可以用于排序,但具体还没想通(以后补上)

    比啥?
    这个要比的方面真是很多,让我们简单举几个例子:

    1。小朋友开始学数学的时候,会被问到“2”和“3”哪个大啊? 这里比较的是简单的数值,在Java中多设计为基本数据类型。

    在 Java 中,用 == 来比较基本数据类型(Primitive Type),直接比较的是值(Value)是否相等。
    equals() 和 compareTo() 都是方法,不适用于基本数据类型。

    2。你一定听过也许是亲自体会过,“你看人家老王家的某某,这次又比你考的好。。。”,这比的啥?成绩,很直观的数据比较。类似还有,你和你弟弟一般高吗?量下身高数据即可。

    这里也是数值,和前面的例子稍不同的是,身高是老王家的某某的一个指标,在 Java 中一般把老王家的某某,定义为某个类比如Person类的一个对象,身高则是他的一个属性。因为对象的属性通常比较多,为了简化问题,在这里让我们做个假设:两个对象是同一个类的对象,只有一个属性。这种情况下如何判断这两个对象是否相同呢?(比如是不是同一个人(Person)?)

    在 Java 中,对于引用类型的对象,可以用重写Object类的equals()方法比较两个对象的属性值,也是看值(Value)是否相等。compareTo()似乎也可以用,不过应该不太常用在这种情况

    3。你老板这天过来找你:小王,你比较下两个品牌电脑上半年的销售情况,我发了两个电子清单给你,下班前给我个报告。“ 这会儿不太好直接进行数据比较了,咋办?你准备写了Java程序来干这活,不然你今晚就得加班了。

    这种情况在 Java 中,这两份文档就得作为引用类型来比较了,equals(), compareTo(),compare() 就派上用场了。== 也可以用,但一般不直接使用,容易出问题。

    怎么比
    写程序前,你先大概浏览了一下两个文件,突然发现怎么内容都差不多嘛,再仔细看看,分明就是同一份清单,可能老板复制了同一份。

    在 Java 中,equals() 和 compareTo(), 包括compare()的实现, 在比较两个对象的时候,都会先做一个判断,判断二者是否是同一对象。这里就用到了 == ,比较的是这两个引用存的是否是同一地址

    public boolean equals (Object x){
      if(this == x) return true;
      ....
    }
    

    可能还有一种情况,你发现,咦,怎么有一份文件是空的?这没法比了。

    在 Java 中,equals()方法 x.equals(null) 返回的是false。 而 x.compareTo(null) 返回的则是NullPointerException,这个得注意了。

    不管怎样,后来终于可以认真比较了,你可能要比较很多方面:

    • 各电脑品牌的销售地域是否相同
    • 各地域销量是否相同
    • 如何按价格排序
    • 如何按销量排序
    • ...

    那么你是要用 equals(), 还是compareTo(), 亦或是compare()?

    我个人的理解:

    1。如果只是需要在某个方法中简单的比较属性值是否相等,用equals()

    在 Java 中,equals() 是 Object 类的方法,有默认实现方法,返回值是boolean。(比如比较 两个String,如果长度不等,返回false, 否则比较各个字符,如均同则返回true)。

    实际应用中,比如Date对象,Java默认的实现方式是比较getTime()毫秒级的,如果你的程序需要比较年月日,这时候可重写equals方法。

    public boolean equals(Object x){
    if (this == x) return true;
    if (x == null) return false;
    if (this.getClass() != x.getClass()) return false; // Not sure what if inheritance?
    Date that = (Date) x;
    if (this.day !=that.day) return false;
    if(this.month!=that.month) return false;
    if (this.year!=that.year) return false;
    return true;
    }

    
    2。如果需要进行排序,可结合compareTo() 和 compare() 方法。
    
    > compareTo():  对象须实现 Comparable 接口 (必须有可比性)
    
    > compare() : Comparator 接口中定义的方法,具体实现时可调用compareTo() 方法。
    
    二者返回值类似,0 表示相同,负数表示排在前,正数表示排在后。
    
    都是排序,有什么特别的区别吗?
    
    > compareTo(): Java 称之为Lexicographically 排序,以String对象为例,从源码可看到,比较的是某一index上的字符的Unicode编码值。
    - 每个index上的字符都相同且字符串长度相等,返回 0
    - 某个index上的字符没有对应的另一字符串Index,返回 字符串长度差值
    - 某个index上的字符有对应Index但是Unicode值不同,返回二者Unicode值的差值
    
    很明显, compareTo() 使用比较局限,适合作为low level的底层调用。
    
    > compare() 则可更灵活,比如按照产品的销售区域,价格,销量等多种方式来排序,则可在类中重写compare()方法,或使用匿名类实现该方法,便于以后的sort方法。
    

    class XX {
    public int compare(Product p1, Product p2){
    return p1.price - p2.price;
    }
    }

    // 匿名类
    Collections.sort(list, new Comparator(){
    @Override
    public int compare(Product p1, Product p2) {
    return p1.price - p2.price;
    }
    }

    
    以上是我的一些粗浅的认识,关于比较这一块有时候的话还得再深入一下。
    
    另外排序也是后续会重点学习的方面,毕竟最基本的算法就是排序算法了。
    
    **如何理解 引用类型的 == 是指向同一个对象? **
    
    我在简书上写了这篇文章,发表后,我分别分享了一份到博客上,一份到我的微信公众号上,
    也就是说,我的博客和公众号上都各有一个link指向我的这篇简书文章。
    
    博客和微信的地址类似于Java中的引用,都指向了同一个对象(简书)。所以此时二者可用==表示指向了同一对象。
    
    ### 参考文章
    [==, .equals(), compareTo(), and compare()](http://www.cnblogs.com/CoolRandy/articles/3676695.html)
  • 相关阅读:
    ubuntu apt-get工作原理
    关联式容器(associative containers)
    qsort()与besearch()
    D&F学数据结构系列——插入排序
    D&F学数据结构系列——二叉堆
    Windows 系统环境变量的配置
    Python 的版本选择与安装细节
    计算机基础知识总结
    PEP 8 -- Python代码格式规则
    day57 Django补充内容(中间件其他方法、jQuery操作cookie、csrf详解和form组件简单使用)
  • 原文地址:https://www.cnblogs.com/learnbydoing/p/6718219.html
Copyright © 2020-2023  润新知