[Java基础] HashCode、equals、==的区别
来源:互联网 发布:pcb仿真软件 编辑:程序博客网 时间:2024/05/22 21:13
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方法,使内存中的内容也相等。
但是,从为了让我们的程序正常运行的角度,我们应当向Effective Java中所言,重载equals的时候,一定要(正确)重载hashCode
使得equals成立的时候,hashCode相等,也就是a.equals(b)->a.hashCode() == b.hashCode(),或者说此时,equals是hashCode相等的充分条件,hashCode相等是equals的必要条件(从数学课上我们知道它的逆否命题:hashCode不相等也不会equals),但是它的逆命题,hashCode相等一定equals以及否命题不equals时hashCode不等都不成立。
总结一下,equals()是对象相等性比较,hashCode()是计算对象的散列值,当然他们的依据是对象的属性。
对于equals,一般我们认为两个对象同类型并且所有属性相等的时候才是相等的,在类中必须改写equals,因为Object类中的equals只是判断两个引用变量是否引用同一对象,如果不是引用同一对象,即使两个对象的内容完全相同,也会返回false。当然,在类中改写这个equals时,你也可以只对部分属性进行比较,只要这些属性相同就认为对象是相等的。
对于hashCode,只要是用在和哈希运算有关的地方,前面提到了,和equals一样,在你的类中也应该改写。当然如果两个对象是完全相同的,那么他们的hashCode当然也是一样的,但是象前面所述,规则可以由你自己来定义,因此两者之间并没有什么必然的联系。
当然,大多数情况下我们还是根据所有的属性来计算hashCode和进行相等性比较。
官方文档定义:
hashcode方法返回该对象的哈希码值。支持该方法是为哈希表提供一些优点,例如,java.util.Hashtable 提供的哈希表。
hashCode 的常规协定是:
在 Java 应用程序执行期间,在同一对象上多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是对象上 equals 比较中所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
如果根据 equals(Object) 方法,两个对象是相等的,那么在两个对象中的每个对象上调用 hashCode 方法都必须生成相同的整数结果。
以下情况不 是必需的:如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么在两个对象中的任一对象上调用 hashCode 方法必定会生成不同的整数结果。但是,程序员应该知道,为不相等的对象生成不同整数结果可以提高哈希表的性能。
实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)
当equals方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
以上这段官方文档的定义,我们可以抽出成以下几个关键点:
1、hashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,hashCode是用来在散列存储结构中确定对象的存储地址的;
2、如果两个对象相同,就是适用于equals(java.lang.Object) 方法,那么这两个对象的hashCode一定要相同;
3、如果对象的equals方法被重写,那么对象的hashCode也尽量重写,并且产生hashCode使用的对象,一定要和equals方法中使用的一致,否则就会违反上面提到的第2点;
4、两个对象的hashCode相同,并不一定表示两个对象就相同,也就是不一定适用于equals(java.lang.Object) 方法,只能够说明这两个对象在散列存储结构中,如Hashtable,他们“存放在同一个篮子里”。
再归纳一下就是hashCode是用于查找使用的,而equals是用于比较两个对象的是否相等的。
- java基础 equals与==区别,String的hashcode
- [Java基础] HashCode、equals、==的区别
- Java--hashcode,equals,==的区别
- Java ==、equals、hashcode的区别
- java ==和equals、equals和hashCode的区别
- Java基础 equals()、hashCode()和 == 区别
- Java基础之==号、equals()和hashCode()区别
- java(15):基础:“==”、equals()和hashCode()的区别
- Java中==、equals()、hashCode()区别
- java中的 hashcode() 、equals() 和==的区别
- Java中equals方法、==和hashCode的区别
- java中equals,hashcode和==的区别
- java中equals,hashcode和==的区别
- java中“==”、equals和hashCode的区别
- Java中equals、==、hashcode的区别
- hashcode,==,equals的区别与联系(JAVA)
- JAVA学习笔记 ---equals、hashcode和==的区别
- java中的==、equals()、hashCode()方法的区别
- 性能调优攻略
- UILabel的一些不常用属性,持续更新
- Android中的类装载器DexClassLoader
- spring的annotation-driven配置事务管理器详解
- oracle定义job执行存储过程方式
- [Java基础] HashCode、equals、==的区别
- C++字符串学习(二)
- Pro Git中文版——Git 基础
- 设计模式之迭代器模式
- hihocoder-1186-求约数
- C++关键字之:explicit
- Android新手入门2016(2)--Mac下的Android开发环境
- 工作中遇到的遇到的问题总结20160307
- 博弈问题之Nim游戏