两个对象值相同(x.equals(y) == true),则一定有相同的hash code;

这是java语言的定义:

因为:Hash,一般翻译做“散列”,也有直接音译为"哈希"的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。
1) 对象相等则hashCode一定相等;
2) hashCode相等对象未必相等。

这也涉及到如何写自定义的hashCode方法的问题:必须符合以上条件。注意条件2中的未必。具体可参见java doc; Effective Java中有更详细论述
本贴来自ZDNetChina中文社区 http://bbs.zdnet.com.cn ,本贴地址:http://bbs.zdnet.com.cn/viewthread.php?tid=362649

== 是比较地址是否相等,JAVA中声明变量都是引用嘛,不同的引用,可能指向同一个地址。

equals 是比较值是否相等。

这种题很容易在面试中被问到。。。

hash code、equals和“==”三者的关系

1.如果是基本变量,没有hashcode和equals方法,基本变量的比较方式就只有==,;

2.如果是变量,由于在java中所有变量定义都是一个指向实际存储的一个句柄(你可以理解为c++中的指针),在这里==是比较句柄的地址(你可以理解为指针的存储地址),而不是句柄指向的实际内存中的内容,如果要比较实际内存中的内容,那就要用equals方法,但是!!!

如果是你自己定义的一个类,比较自定义类用equals和==是一样的,都是比较句柄地址,因为自定义的类是继承于object,而object中的equals就是用==来实现的,你可以看源码。

那为什么我们用的String等等类型equals是比较实际内容呢,是因为String等常用类已经重写了object中的equals方法,让equals来比较实际内容,你也可以看源码。

3. hashcode
在一般的应用中你不需要了解hashcode的用法,但当你用到hashmap,hashset等集合类时要注意下hashcode。

你想通过一个object的key来拿hashmap的value,hashmap的工作方法是,通过你传入的object的hashcode在内存中找地址,当找到这个地址后再通过equals方法来比较这个地址中的内容是否和你原来放进去的一样,一样就取出value。

所以这里要匹配2部分,hashcode和equals
但假如说你new一个object作为key去拿value是永远得不到结果的,因为每次new一个object,这个object的hashcode是永远不同的,所以我们要重写hashcode,你可以令你的hashcode是object中的一个恒量,这样永远可以通过你的object的hashcode来找到key的地址,然后你要重写你的equals方法,使内存中的内容也相等。。。

首先,从语法角度,也就是从强制性的角度来说,hashCode和equals是两个独立的,互不隶属,互不依赖的方法,equals成立与hashCode相等这两个命题之间,谁也不是谁的充分条件或者必要条件。

但是,从为了让我们的程序正常运行的角度,我们应当向Effective Java中所言

重载equals的时候,一定要(正确)重载hashCode

使得equals成立的时候,hashCode相等,也就是a.equals(b)->a.hashCode() == b.hashCode(),或者说此时,equals是hashCode相等的充分条件,hashCode相等是equals的必要条件(从数学课上我们知道它的逆否命题:hashCode不相等也不会equals),但是它的逆命题,hashCode相等一定equals以及否命题不equals时hashCode不等都不成立。

所以,如果面试的时候,最好把hashCode与equals之间没有强制关系,以及根据(没有语法约束力的)规范的角度,应当做到...这两层意思都说出来:P

总结一下,equals()是对象相等性比较,hashCode()是计算对象的散列值,当然他们的依据是对象的属性。

对于equals,一般我们认为两个对象同类型并且所有属性相等的时候才是相等的,在类中必须改写equals,因为Object类中的equals只是判断两个引用变量是否引用同一对象,如果不是引用同一对象,即使两个对象的内容完全相同,也会返回false。当然,在类中改写这个equals时,你也可以只对部分属性进行比较,只要这些属性相同就认为对象是相等的。

对于hashCode,只要是用在和哈希运算有关的地方,前面提到了,和equals一样,在你的类中也应该改写。当然如果两个对象是完全相同的,那么他们的hashCode当然也是一样的,但是象前面所述,规则可以由你自己来定义,因此两者之间并没有什么必然的联系。

当然,大多数情况下我们还是根据所有的属性来计算hashCode和进行相等性比较。

hashcode、equals和 ==详解的更多相关文章

  1. java中hashcode()和equals()的详解

    今天下午研究了半天hashcode()和equals()方法,终于有了一点点的明白,写下来与大家分享(zhaoxudong 2008.10.23晚21.36). 1. 首先equals()和hashc ...

  2. java中==和equals和hashcode的区别详解

    一.相同点 都是用来进行值或对象的比较. 二.不同点 对于“==”而言,对于基本类型(char,byte,short,int,long,float,double,boolean),对比的是值,所以是相 ...

  3. Java之equals和==详解

    两者的区别: A:== 基本类型:比较的是值是否相同 引用类型:比较的是地址值是否相同 B:equals() 只能比较引用类型. 默认情况下,比较的是地址值是否相同,因为我们可以看源代码可以看到,在O ...

  4. java中String与equals,==详解

    首先,String str1="abc",这个str1所指向的是常量池中的一块内存. 如果又有,String str2="abc",那么str1和str2所指向 ...

  5. equals()方法详解

    Java语言中equals()方法的使用可以说比较的频繁,但是如果轻视equals()方法,一些意想不到的错误就会产生.哈哈,说的有点严重了~ 先谈谈equals()方法的出身.equals()方法在 ...

  6. toString()和equals()方法详解

    一:toString()方法 Object中toString方法 public String toString() { return getClass().getName() + "@&qu ...

  7. Java中String 的equals 和==详解

    一.Java中数据存储区域包括: 1.寄存器:最快的存储区,由编译器根据需求进行分配,我们在程序中无法控制. 2. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new ...

  8. Java 字符串比较,String 中的一些方法 == 和 equals 的详解

    "==" 是比较的是两个对象的内存地址,而equals方法默认情况下是比较两个对象的内存地址. 1.String str = "hello"  生成的字符串,首 ...

  9. java数组、java.lang.String、java.util.Arrays、java.lang.Object的toString()方法和equals()方法详解

    public class Test { public static void main(String[] args) { int[] a = {1, 2, 4, 6}; int[] b = a; in ...

随机推荐

  1. Hadoop化繁为简(三)—探索Mapreduce简要原理与实践

    目录-探索mapreduce 1.Mapreduce的模型简介与特性?Yarn的作用? 2.mapreduce的工作原理是怎样的? 3.配置Yarn与Mapreduce.演示Mapreduce例子程序 ...

  2. Compile SQLite3 from individual files

    下载非Amalgamation SQLite3源码 安装tcl, apt-get instal tcl 解压 mkdir build cd build ../configure make #make ...

  3. 深入浅出的理解框架(Struts2、Hibernate、Spring)与 MVC 设计模式

    现在许许多多的初学者和程序员,都在趋之若鹜地学习Web开发的宝典级框架:Struts2,Spring,Hibernate.似乎这些框架成为了一个人是否精通Java,是否会写J2EE程序的唯一事实标准和 ...

  4. docker-compose中启动镜像失败的问题

    http://blog.csdn.net/boling_cavalry/article/details/79050451 解决docker-compose启动镜像失败的问题: 原文地址:http:// ...

  5. eclipse里面使用Maven搭建web工程

    一.建立Maven项目 使用Eclipse的maven构建一个web项目,以构建SpringMVC项目为例: 1.1 选择建立Maven Project 选择File -> New -> ...

  6. npm install node-sass失败

    Cannot download "https://github.com/sass/node-sass/releases/download/v3.8.0/win32-x64-46_bindin ...

  7. 使用yocs_velocity_smoother对机器人速度进行限制

    yocs_velocity_smoother是一个速度.加速度限制器,用来防止robot navigation的速度/转速过快,加速度/快减速过大.Bound incoming velocity me ...

  8. java 对一个字符串进行加减乘除的运算

    记录一个小程序,里面涉及到的JAVA知识点有:字符串扫描,list删除元素的方法,泛型的使用,JAVA中的/要注意的事项.有兴趣的可以看看 package com.demo; import java. ...

  9. arcgis server瓦片行列号计算

    2013-08-01 arcgis server切图时会设置一个原点坐标,如果是经纬度坐标一般默认(x0,y0)=(-400,400)作为切图的起始点,即从这开始算行列号.假设切图的地图某点坐标为x, ...

  10. 为何float有效位数为7位?

    为何float有效位数为7位? 首先我们应该明确一点:C语言中,%f表示保留7位有效数字7位有效数字: 是指 整数部分 和小数部分一共7位 单精度数的尾数用23位存储,加上默认的小数点前的1位1,2^ ...