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

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)
Java 比较(==, equals, compareTo, compare)的更多相关文章
- Java中的equals,==,compareTo和compare的比较
Java中的equals(),==,compareTo()和compare() 首先只有==可以用作两个基本类型数据之间的比较,当然是值比较.当用作两个对象比较时,比较的是对象引用,而不是值比较. 其 ...
- Java中“==”、“compareTo()”和“equals()”的区别
在比较两个对象或者数据大小的时候,经常会用到==.compareTo()和equals(),尤其是在接入了Comparable接口后重写compareTo方法等场景,所以我们来理一下这三个的区别. 1 ...
- Android 开发笔记 “java.util.Calendar.compareTo()”
java.util.Calendar.compareTo() 方法比较Calendar对象和anotherCalendar对象之间的时间值(毫秒偏移量). 声明 以下是java.util.Calen ...
- java中的compareto方法的详细介绍
java中的compareto方法的详细介绍 Java Comparator接口实例讲解(抽象方法.常用静态/默认方法) 一.java中的compareto方法 1.返回参与比较的前后两个字符串的as ...
- Java中equals与==和comparaTo的区别
一.先说说Java中equals和==的区别: Java中的数据类型,可分为两类: 1.基本数据类型(也叫原始数据类型) 八大基本数据类型 char byte short int long doubl ...
- Java基础-比较运算符Compare Operators
Java基础-比较运算符Compare Operators 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.关系运算符 关系运算符包括: 1>.大于(>) 2> ...
- java中的compareto方法以及LIst列表排序的详细介绍【转】
java中的compareto方法的详细介绍 javacompareTo java中的compareto方法,返回参与比较的前后两个字符串的asc码的差值,看下面一组代码 String a=&quo ...
- Java的equals方法的使用技巧
Java的equals方法的使用技巧 1.业务场景: 在某个社交软件中,要求每个用户的用户名(name)必须独一无二,那么在每次增加新用户的时候,都要对该用户的注册名进行判断,如果当前用户名已经被占用 ...
- Effective Java —— 覆盖equals时遵守通用约定
本文参考 本篇文章参考自<Effective Java>第三版第十条"Obey the general contract when overriding equals" ...
随机推荐
- 【Java集合类】ArrayList详解 (JDK7)
相信对于使用过Java的人来说,ArrayList这个类大家一定不会陌生. 数据结构课上讲过, Array是数组,它能根据下标直接找到相应的地址,所以索引速度很快,但是唯一的缺点是不能动态改变数组的长 ...
- Java Trie树
Tire树,又叫字典树,主要是用来查找单词,词频统计的. 老规矩,直接上代码. package tireTree; public class TireTree { TireNode root; pub ...
- (七)javascript中的数组
一. 一维数组 1.1 声明数组 var 数组名=new Array(数组大小); 1.2 添加元素 <script> var a=new Array(3); a[0]="张三 ...
- Python 之 json 模块
引言 对于做web开发的人来说,json文本必须要熟知与熟练使用的.大部分网站的API接口调用返回的数据,就是json格式的.如果看json对象所包含的内容,相信对熟悉Python的人开说,很快就能把 ...
- 算法模板——Tarjan强连通分量
功能:输入一个N个点,M条单向边的有向图,求出此图全部的强连通分量 原理:tarjan算法(百度百科传送门),大致思想是时间戳与最近可追溯点 这个玩意不仅仅是求强连通分量那么简单,而且对于一个有环的有 ...
- require和include的区别及自动加载的定义
//引入文件//require与include的区别://include主要是指引入,如果引入的文件出现错误,则程序停止运行//require主要是指请求,如果请求的文件出现错误,则程序不受影响,继续 ...
- 跨平台的.NET邮件协议MailKit组件解析
发起的.NET Core开源组织号召,进展的速度是我自己也没有想到的,很多园友都积极参与(虽然有些人诚心砸场子,要是以我以前的宝脾气,这会应该被我打住院了吧,不过幸好是少数,做一件事总有人说好,也有人 ...
- Spring Data操作Redis详解
Spring Data操作Redis详解 Redis是一种NOSQL数据库,Key-Value形式对数据进行存储,其中数据可以以内存形式存在,也可以持久化到文件系统.Spring data对Redis ...
- java学习笔记 --- 方法
一.方法 (1)方法:就是完成特定功能的代码块. 注意:在很多语言里面有函数的定义,而在Java中,函数被称为方法. (2)格式: 修饰符 返回值类型 方法名(参数类型 参数名1,参数类型 ...
- 关于 Python generator(生成器)的类比
Python 的生成器运用仿佛是最完美的 xing爱,生成器本身和循环代表男女,结束代表同时达到高潮,不是很精准,但很有趣啊!哈哈哈,一下记住了