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. 数学(莫比乌斯反演):HAOI 2011 问题B

    题目描述: 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. 输入格式: 第一行一个整数n,接下来n ...

  2. 线性代数(矩阵乘法):POJ 3233 Matrix Power Series

    Matrix Power Series   Description Given a n × n matrix A and a positive integer k, find the sum S = ...

  3. Java Topology Suite (JTS)与空间数据模型

    JTS是Java的处理地理数据的API,它提供以下功能: 实现了OGC关于简单要素SQL查询规范定义的空间数据模型 一个完整的.一致的.基本的二维空间算法的实现,包括二元运算(例如touch和over ...

  4. iOS __block用法

    没有__block qualifier的primitive c types会直接在创建block的时候被capture到block里.有__block qualifier的话,会在调用block的时候 ...

  5. Java 内省 Introspector

    操纵类的属性,有两种方法 反射 内省 面向对象的编程中,对于用户提交过来的数据,要封装成一个javaBean,也就是对象 其中Bean的属性不是由字段来决定的,而是由get和Set方法来决定的 pub ...

  6. Python Logging 模块研究

    背景在一个新的项目里面加入了日志功能,想自己写一个,但是一个偶然的机会,通过google发现Python内建了一个非常强大的日志(log)模块:l... 背景 在一个新的项目里面加入了日志功能,想自己 ...

  7. Linux 上Oracle RAC 10g 升级到 Oracle RAC 11g

    了解如何在 Oracle Enterprise Linux 5 上逐步将 Oracle RAC 10g 第 2 版升级到 Oracle RAC 11g. Oracle 数据库 11g(即,新一代网格计 ...

  8. Visual studio 2008 的语法高亮插件 NShader

    前段时间一直在使用matlab,今天需要使用vs2008,而用惯了matlab,习惯了其中一项选中变量高亮的设置,突然回来使用VS,感到各种不适应,顿时想到了一个词:矫情 呵呵,于是在网上找各种插件, ...

  9. 禁止执行某些讨厌的程序,如tadb.exe

    第一步:首先通过快捷键"Win+R"来打开"执行"菜单. 第二步:输入"gpedit.msc"回车确认,进入我们电脑中的组策略编辑器. 第三 ...

  10. Error parsing XML: not well-formed (invalid token) 报错+R文件消失解决的方法

    xml报错: 这个xml文件上右键source ->format 注意:res下的文件名称不能大写 R文件消失: 在攻克了其它问题的情况下(或者其它问题还没解决先凝视掉) 手动删除gen pro ...