java当中所有的类都继承于Object这个基类,在object中的基类定义了一个equals方法,public boolean equals(Object obj) {

    return (this == obj);}这个方法的初始行为是比较引用,但在一些类库中这个方法被覆盖掉了,如String,Integer,Date等在这些类中equals有其自身的实现,而不再是比较对象在栈内存中的地址(即引用)了,如果不覆盖,则equals默认行为是比较引用。

对于引用数据类型之间进行equals比较,在没有覆盖equals方法的情况下,他们之间的比较还是基于对象的引用,因为object的equals方法也是用==进行比较的,所有比较后的结果与双等号的结果相同。

  如果我们希望equals比较的不再是引用,我们就需要覆写equals方法。  

  equals 方法在非空对象引用上实现相等关系:

  • 自反性:对于任何非空引用值 xx.equals(x) 都应返回 true
  • 对称性:对于任何非空引用值 xy,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true
  • 传递性:对于任何非空引用值 xyz,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true
  • 一致性:对于任何非空引用值 xy,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。
  • 对于任何非空引用值 xx.equals(null) 都应返回 false

  举一个覆写了equals的例子:

 class Strudent{
private int age;
private String name;
......//构造函数以及setter和getter
public boolean equals(Object obj){
boolean result=false;
if(obj==null){//若传入的对象为空
result=false;
}
if(this==obj){//若传入的对象和Student对象的引用相同,则表示指向了同一个堆内存中的对象
result=true;
}
if(obj instanceof Student){//obj对象是否是Student类的实例
Student stu=(Student)obj;//将Object类向下转型为Student类
if(stu.getName().equals(this.name)&&stu.getAge()==this.age)//这里的equals方法调用的是String类库中已被覆写过的equals方法,因getName()返回的String类型的值
result=true;
}else{
result= false;
}
return result;
}
}

  注意:当equals方法被覆写时,通常有必要覆写hashCode方法,以维护hashCode方法的常规规定,该协定声明相等的对象必须具有相等的哈希码。

  上面代码中的hashCode()方法可以这样写:public int hashCode(){ return (this.name.hashCode()+this.age)*31;}

  在覆写了equals方法的类中,必须也覆写hashCode方法,如果不覆盖“键”的hashCode()和equals(),那么使用散列的数据结构(HashSet, HashMap, LinkedHashSet, LinkedHashMap)就无法正确地处理你的“键”。

  hashCode()这个方法也是在object类中定义的:public native int hashCode();

  hashCode()是一个本地方法,它的实现与本地机器相关。hashCode()生成对象的哈希码值,它默认是使用对象的地址计算出的哈希码,返回的是整数类型,如果没有覆写hashCode()方法,任何对象的哈希码值都是不相等的。而设计hashCode的最重要的因素就是:无论何时,对同一个对象调用hashCode()都应该生成同样的值。如果在将一个对象用put()添加进HashMap时产生一个hashCode()值,而在用get()取出时却产生了另一个hashCode()值,那么就无法重新取得该对象了。所以,如果你的hashCode()方法依赖于对象中易变的数据,那么当数据变化时,hashCode就会生成一个不同的哈希码,相当于产生了一个不同的键。也不应该使hashCode()依赖于具有唯一性的对象信息,尤其是使用this的值,这只能产生很糟糕的hashCode(),因为这样做无法生成一个新的键,使之与put()中原始的键值对中的键相同。

  要想使hashCode()实用,它的速度必须快,而且必须有意义。也就是说,它必须基于对象的内容生成哈希码。哈希码不必是独一无二的(应该更关注生成速度,而不是唯一性),但是通过hashCode()和equals(),必须能够完全确定对象的身份。

  hashCode()的返回值(哈希码值)和equals()的关系如下:

  如果x.equals(y)返回“true",那么x和y的hashCode()必须相等。

  如果x.equals(y)返回”false",那么x和y的hashCode()有可能相等,也有可能不相等。

还有注意:String、Integer、Boolean、Double等这些类都覆写了equals和hashCode方法,这个两个方法是根据对象的内容来比较和计算哈希码值的。所以,主要对象的基本类型值相同,那么哈希码值就一定相同。

equals和hashcode的更多相关文章

  1. How to implement equals() and hashCode() methods in Java[reproduced]

    Part I:equals() (javadoc) must define an equivalence relation (it must be reflexive, symmetric, and ...

  2. JAVA中用堆和栈的概念来理解equals() "=="和hashcode()

    在学习java基本数据类型和复杂数据类型的时候,特别是equals()"=="和hashcode()部分时,不是很懂,也停留了很长时间,最后终于有点眉目了. 要理解equals() ...

  3. 关于equals、hashcode和集合类的小结

    一.首先明确一点:equals()方法和hashcode()方法是Object类里的方法. 查看源码可以知道,在Object类中equals(obj)方法直接返回的是  this == obj 的值. ...

  4. Object方法equals、hashCode

    java知识背景: 1)hashCode()方法返回的是Jvm的32位地址 2)==比较的是对象在jvm中的地址 3)Object的equals()比较的就是jvm物理地址 4)比较2个对象使用equ ...

  5. Java中的equals和hashCode方法

    本文转载自:Java中的equals和hashCode方法详解 Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要 ...

  6. Java提高篇——equals()与hashCode()方法详解

    java.lang.Object类中有两个非常重要的方法: 1 2 public boolean equals(Object obj) public int hashCode() Object类是类继 ...

  7. Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例(转)

    Java中==.equals.hashcode的区别与重写equals以及hashcode方法实例  原文地址:http://www.cnblogs.com/luankun0214/p/4421770 ...

  8. java中equals和hashCode方法的解析

    解析Java对象的equals()和hashCode()的使用 前言 在Java语言中,equals()和hashCode()两个函数的使用是紧密配合的,你要是自己设计其中一个,就要设计另外一个.在多 ...

  9. Java实战equals()与hashCode()

    一.equals()方法详解 equals()方法在object类中定义如下: 代码 public boolean equals(Object obj) { return (this == obj); ...

  10. 一次性搞清楚equals和hashCode

    前言 在程序设计中,有很多的“公约”,遵守约定去实现你的代码,会让你避开很多坑,这些公约是前人总结出来的设计规范. Object类是Java中的万类之祖,其中,equals和hashCode是2个非常 ...

随机推荐

  1. ab压测 apr_socket_recv: Connection reset by peer (104)错误解决方法

    用apache自带ab命令进行压测,报了如下错误: 原因是在ab的程序源码中对并发数有限制. 解决办法:修改apache源码support下面的ab.c源代码,然后重新编译.修改内容如下:

  2. 【转】onPrepareOptionsMenu 和onCreateOptionsMenu 的区别

    原文网址:http://blog.csdn.net/allenjy123/article/details/7467084 @Override public boolean onCreateOption ...

  3. 动态规划:NOI2013 快餐店

    Description 小 T打算在城市C开设一家外送快餐店.送餐到某一个地点的时间与外卖店到该地点之间最短路径长度是成正比的,小T希望快餐店的地址选在离最远的顾客距离最近 的地方. 快餐店的顾客分布 ...

  4. 【动态规划】【KMP】HDU 5763 Another Meaning

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5763 题目大意: T组数据,给两个字符串s1,s2(len<=100000),s2可以被解读成 ...

  5. 搭建ftp环境

    首先明确,ftp站点设置在服务器上,而在客户端上来使用ftp工具来进行上传文件 具体环境搭建如下两个链接,一个server2003,一个是win7 server2003:http://jingyan. ...

  6. HDOJ(HDU) 2153 仙人球的残影(谜一样的题、、、)

    Problem Description 在美丽的HDU,有一名大三的同学,他的速度是众所周知的,跑100米仅仅用了2秒47,在他跑步过程中会留下残影的哎,大家很想知道他是谁了吧,他叫仙人球,既然名字这 ...

  7. Velocity常用方法

    1.字符串替换 replace#if($!{name} != '')#set($tempName = $!{name})#set($tempName = $tempName.Replace('abc' ...

  8. GPS

    百度百科   http://baike.baidu.com/link?url=Kl6eLdP-fveCsHt1wHF8TVuOR9wkT2K3qFnWy36PcaYaB1hdgOS_cnTEB0jIg ...

  9. 《University Calculus》-chape4-导数的应用-极值点的二阶导数检验法

    函数凹凸性检验: 很容易看到,观察类似抛物线这类曲线,能够看到它们有一个向上凹或者向下凹的这样一个过程,而我们将这个过程细化并观察一系列点的导数的变化情况我们给出如下的定义: (1)如果函数图像在区间 ...

  10. 提升ReSharper和Visual Studio的性能

    转载 作者:赵青青        出处:http://www.cnblogs.com/zhaoqingqing/ 文章目录[点击展开](?)[+]   提升性能 我们不断地确保ReSharper的正常 ...