java中hashcode()和equals()的详解
2015-01-08 16:14
204 查看
下面是关于hashcode()和equals()的官方文档解释
返回该对象的哈希码值。支持此方法是为了提高哈希表(例如
在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用
如果根据
实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)
返回:此对象的一个哈希码值。
指示其他某个对象是否与此对象“相等”。
自反性:对于任何非空引用值
对称性:对于任何非空引用值
传递性:对于任何非空引用值
一致性:对于任何非空引用值
对于任何非空引用值
注意:当此方法被重写时,通常有必要重写 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,他们“存放在同一个桶里”。
5、两个对象的hashCode不同,则equals(java.lang.Object) 一定不同。
本段摘自互联网
1.hashcode是用来查找的,如果你学过数据结构就应该知道,在查找和排序这一章有
例如内存中有这样的位置
0 1 2 3 4 5 6 7
而我有个类,这个类有个字段叫ID,我要把这个类存放在以上8个位置之一,如果不用hashcode而任意存放,那么当查找时就需要到这八个位置里挨个去找,或者用二分法一类的算法。
但如果用hashcode那就会使效率提高很多。
我们这个类中有个字段叫ID,那么我们就定义我们的hashcode为ID%8,然后把我们的类存放在取得得余数那个位置。比如我们的ID为9,9除8的余数为1,那么我们就把该类存在1这个位置,如果ID是13,求得的余数是5,那么我们就把该类放在5这个位置。这样,以后在查找该类时就可以通过ID除 8求余数直接找到存放的位置了。
2.但是如果两个类有相同的hashcode怎么办呢(我们假设上面的类的ID不是唯一的),例如9除以8和17除以8的余数都是1,那么这是不是合法的,回答是:可以这样。那么如何判断呢?在这个时候就需要定义 equals了。
也就是说,我们先通过 hashcode来判断两个类是否存放某个桶里,但这个桶里可能有很多类,那么我们就需要再通过 equals 来在这个桶里找到我们要的类。
那么。重写了equals(),为什么还要重写hashCode()呢?
想想,你要在一个桶里找东西,你必须先要找到这个桶啊,你不通过重写hashcode()来找到桶,光重写equals()有什么用啊
看下面的例子:
hashCode
public int hashCode()返回该对象的哈希码值。支持此方法是为了提高哈希表(例如
java.util.Hashtable提供的哈希表)的性能。
hashCode的常规协定是:
在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用
hashCode方法都必须生成相同的整数结果。
如果根据
equals(java.lang.Object)方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不 要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。
实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)
返回:此对象的一个哈希码值。
equals
public boolean equals(Object obj)指示其他某个对象是否与此对象“相等”。
equals方法在非空对象引用上实现相等关系:
自反性:对于任何非空引用值
x,
x.equals(x)都应返回
true。
对称性:对于任何非空引用值
x和
y,当且仅当
y.equals(x)返回
true时,
x.equals(y)才应返回
true。
传递性:对于任何非空引用值
x、
y和
z,如果
x.equals(y)返回
true,并且
y.equals(z)返回
true,那么
x.equals(z)应返回
true。
一致性:对于任何非空引用值
x和
y,多次调用 x.equals(y) 始终返回
true或始终返回
false,前提是对象上
equals比较中所用的信息没有被修改。
对于任何非空引用值
x,
x.equals(null)都应返回
false。
Object类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值
x和
y,当且仅当
x和
y引用同一个对象时,此方法才返回
true(
x == y具有值
true)。
注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
参数:
obj- 要与之比较的引用对象。返回:如果此对象与 obj 参数相同,则返回
true;否则返回
false。
对上面的艰涩的翻译语言进行整理:
1、hashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,hashCode是用来在散列存储结构中确定对象的存储地址的;
2、如果两个对象相同(及两个对象的地址值相同),就是适用于equals(java.lang.Object) 方法,那么这两个对象的hashCode一定要相同;
3、如果对象的equals方法被重写,那么对象的hashCode也尽量重写,并且产生hashCode使用的对象,一定要和equals方法中使用的一致,否则就会违反上面提到的第2点;
4、两个对象的hashCode相同,并不一定表示两个对象就相同,也就是不一定适用于equals(java.lang.Object) 方法,只能够说明这两个对象在散列存储结构中,如Hashtable,他们“存放在同一个桶里”。
5、两个对象的hashCode不同,则equals(java.lang.Object) 一定不同。
本段摘自互联网
1.hashcode是用来查找的,如果你学过数据结构就应该知道,在查找和排序这一章有
例如内存中有这样的位置
0 1 2 3 4 5 6 7
而我有个类,这个类有个字段叫ID,我要把这个类存放在以上8个位置之一,如果不用hashcode而任意存放,那么当查找时就需要到这八个位置里挨个去找,或者用二分法一类的算法。
但如果用hashcode那就会使效率提高很多。
我们这个类中有个字段叫ID,那么我们就定义我们的hashcode为ID%8,然后把我们的类存放在取得得余数那个位置。比如我们的ID为9,9除8的余数为1,那么我们就把该类存在1这个位置,如果ID是13,求得的余数是5,那么我们就把该类放在5这个位置。这样,以后在查找该类时就可以通过ID除 8求余数直接找到存放的位置了。
2.但是如果两个类有相同的hashcode怎么办呢(我们假设上面的类的ID不是唯一的),例如9除以8和17除以8的余数都是1,那么这是不是合法的,回答是:可以这样。那么如何判断呢?在这个时候就需要定义 equals了。
也就是说,我们先通过 hashcode来判断两个类是否存放某个桶里,但这个桶里可能有很多类,那么我们就需要再通过 equals 来在这个桶里找到我们要的类。
那么。重写了equals(),为什么还要重写hashCode()呢?
想想,你要在一个桶里找东西,你必须先要找到这个桶啊,你不通过重写hashcode()来找到桶,光重写equals()有什么用啊
看下面的例子:
package com.java.hashcode; public class hashcode { int id; public int getId() { return id; } public void setId(int id) { this.id = id; } @Override public int hashCode() { // 重新hashcode方法 hashcode值相同。 return this.id; } public hashcode() { } }客户端
package com.java.hashcode; import java.util.HashSet; public class hashcodeTest { /** * @param args */ public static void main(String[] args) { HashSet<hashcode> ha=new HashSet<hashcode>(); hashcode a = new hashcode(); hashcode b = new hashcode(); a.setId(1); b.setId(1); System.out.println(a.hashCode()==b.hashCode());//hashcode值相同 System.out.println(a.equals(b));//hashcode值相同,但是两个对象不相等。我们没有重写object的equal方法,所以会调用默认的equals方法,比较两个对象的 //地址值,发现不是同一个对象 ha.add(a); ha.add(b); System.out.println(ha);//默认的是getClass().getName() + '@' + Integer.toHexString(hashCode()),类名+@+hashcode值 /** * 运行结果: * true false [com.java.hashcode.hashcode@1, com.java.hashcode.hashcode@1] hashset里面包含相同的对象,显然这个不符合hashset的定义,下面我们就要重新定义equals方法。 */ } }下面重新定义equals方法:
package com.java.hashcode; public class hashcode { int id; String name; int[] array;//思考一下?我们定义了,name 字段和一个整形数组 equals是时候该怎么样比较? 是比较他们的存储地址?还是比较他们的值?数组又该如何去比较? //我觉得应该是比较他们的值,你觉得呢? 但是数组比较就会很麻烦,记得原来学习集合框架的时候,hashset中最好是添加固定不变的对象,像这种有不确定值 //的对象,比较的确好麻烦啊 public int[] getArray() { return array; } public void setArray(int[] array) { this.array = array; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } @Override public int hashCode() { // 重新hashcode方法 hashcode值相同。 return this.id; } public hashcode() { } @Override public boolean equals(Object obj) { if(obj==null){ return false; } if(obj==this){ return true; } if (obj instanceof hashcode) { //obj和this是同一类对象,看属性值是否相同 hashcode hs = (hashcode) obj; if (hs.id == this.id) { return true; } } return false; } }客户端:
package com.java.hashcode; import java.util.HashSet; public class hashcodeTest { /** * @param args */ public static void main(String[] args) { HashSet<hashcode> ha = new HashSet<hashcode>(); hashcode a = new hashcode(); hashcode b = new hashcode(); a.setId(1); b.setId(1); System.out.println(a.hashCode() == b.hashCode());// hashcode值相同 System.out.println(a.equals(b));// hashcode值相同,但是两个对象不相等。调用我们重写object的equal方法。 ha.add(a); ha.add(b); System.out.println(ha);// 默认的是getClass().getName() + '@' + // Integer.toHexString(hashCode()),类名+@+hashcode值 // 运行结果: // true // true // [com.java.hashcode.hashcode@1] // 调用我们覆盖的父类的equals方法,两个对象比较会认为他们是同一个对象。 } }
相关文章推荐
- java中hashcode()和equals()的详解
- java中的hashcode()和equals()方法详解
- java中hashcode()和equals()的详解
- java中hashcode()和equals()的详解
- Java中的hashcode()和equals()方法详解
- java中hashcode()和equals()的详解
- java中hashcode()和equals()的详解
- java中hashcode()和equals()的详解
- java中hashcode()和equals()的详解
- java中hashcode()和equals()的详解(转载)
- Java中的hashcode()和equals()方法详解
- java中hashcode()和equals()的详解
- [转]java中hashcode()和equals()的详解
- java中hashcode()与equals()详解
- java中hashcode()和equals()的详解
- java中hashcode()和equals()的详解
- java中hashcode()和equals()的详解
- java中hashcode()和equals()的详解[转]
- java中hashcode()和equals()的详解
- java中hashcode()和equals()的详解