两个对象值相同(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. CocosCreator资源工作流程

    --摘自官方文档 资源工作流程 添加资源 资源管理器 提供了三种在项目中添加资源的方式: 通过 创建按钮 添加资源 在操作系统的文件管理器中,将资源文件复制到项目资源文件夹下,之后再打开或激活 Coc ...

  2. python面向对象笔记

    一.封装(属性/私有方法/公有方法/静态方法/构造函数...) # 定义一个类 class Animal: # 私有成员(用_开头的约定为私有成员 - 注:仅仅是君子协定) _age = 0 # 构造 ...

  3. Ftrace使用指南及跟踪系统调用

    http://vonnyfly.github.io/2013/06/24/ftraceshi-yong-zhi-nan/

  4. mybatis传入List实现批量更新的坑

    原文:http://www.cnblogs.com/zzlback/p/9342329.html 今天用mybatis实现批量更新,一直报错,说我的sql语句不对,然后我还到mysql下面试了,明明没 ...

  5. Map和String类型之间的转换

    前提是String的格式是map或json类型的 public static void main(String[] args) { Map<String,Object> map = new ...

  6. .Net AppDomain详解(二)

    AppDomain 类 表示应用程序域,它是一个应用程序在其中执行的独立环境. 此类不能被继承. 命名空间:   System程序集:  mscorlib(位于 mscorlib.dll) 继承层次结 ...

  7. AndroidStudio下加入百度地图的使用(四)——路线规划

    上一章中我们已经完成了API常用的方法及常量属性的使用,这一章向大家介绍一下地图的重要功能-路线规划. (1) 定义API中的路线查询类: RoutePlanSearch mSearch = Rout ...

  8. SoapUI Pro Project Solution Collection-Custom project and setup

    import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import com.eviware.soap ...

  9. 使用SpringBoot Admin监控SpringCloud微服务

    spring-boot admin的github地址:https://github.com/codecentric/spring-boot-admin 本文基于SpringCloud的环境和配置上增加 ...

  10. CentOS下网卡启动、配置等ifcfg-eth0教程(转)

    步骤1.配置/etc/sysconfig/network-scripts/ifcfg-eth0 里的文件.it动力的CentOS下的ifcfg-eth0的配置详情: [root@localhost ~ ...