是每个JAVA对象都对应一个自己的HASHCODE吗?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是每个JAVA对象都对应一个自己的HASHCODE吗?相关的知识,希望对你有一定的参考价值。
这就出现了一个问题:JAVA对象可以创建无穷大个,而HASHCODE不管是什么数据类型,最后数量都是有限的吧?我们怎么能把无穷大的东西用有限的数量来表示呢?
大家似乎没有击中问题要害。。。。
我想问,既然HASHCODE是一个有限的类型,它怎么能表示无限的对象呢?最终肯定有N多对象将生成一样的HASHCODE....
我们不能把无穷大用一个有穷的东西来表示出来啊
直接查的API,看看对你有帮助没。
java.lang.Object对hashCode()的描述。
(附上其定义 public native int hashCode();是一个抽象方法)
hashCode
public int hashCode()返回该对象的哈希码值。支持此方法是为了提高哈希表(例如 java.util.Hashtable 提供的哈希表)的性能。
hashCode 的常规协定是:
在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。
如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不 要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。
实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)
返回:
此对象的一个哈希码值。
另请参见:
equals(java.lang.Object), Hashtable
顺便把equals和Hashtable的hashCode贴出来
java.lang.Object的equals定义:
public boolean equals(Object obj)
return (this == 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。
另请参见:
hashCode(), Hashtable
java.util.HashTable对hashCode的实现。
public synchronized int hashCode()
/*
* This code detects the recursion caused by computing the hash code
* of a self-referential hash table and prevents the stack overflow
* that would otherwise result. This allows certain 1.1-era
* applets with self-referential hash tables to work. This code
* abuses the loadFactor field to do double-duty as a hashCode
* in progress flag, so as not to worsen the space performance.
* A negative load factor indicates that hash code computation is
* in progress.
*/
int h = 0;
if (count == 0 || loadFactor < 0)
return h; // Returns zero
loadFactor = -loadFactor; // Mark hashCode computation in progress
Entry[] tab = table;
for (int i = 0; i < tab.length; i++)
for (Entry e = tab[i]; e != null; e = e.next)
h += e.key.hashCode() ^ e.value.hashCode();
loadFactor = -loadFactor; // Mark hashCode computation complete
return h;
你还可以看看Map接口中对equals和hashCode的定义。
你还可以看看Map 参考技术A JAVA对象可以创建无穷多个,只是理论上的说法,因为内存是有限的,所以只能创建有限多个。
所以是有限多个对象用有限多个hash值对应,而不是无限多个对象用有限多个hash值对应本回答被提问者采纳 参考技术B 一个对象无论大小它只代表一个内存地址,这也是为何java会有个名词叫引用对象,其实更确切的应该称为引用对象地址~ 参考技术C 应该是的,但这是计算来的,不用你自己设定,而且没必要存储,它的HashCode是通过自身的字段定义得到的,用的时候调用发就可以得到。
对hashcodeequals的理解
1、首先hashcode和equals都是java每个对象都存在的方法,因为他们两是Object的方法。
2、hashcode方法默认返回的是该对象内存地址的哈希码,然而你会发现,Object类中没有此方法的实现,是一个native方法,由c++实现,java只负责调用。像String等都对hashcode实现了重写,同样也对equals进行了重写,已达到自己的需求。
3、equals方法默认返回的是 this==o,也就是判断两个对象的地址是否相同,如果相同则返回true,否则false;这样你就会发现当你比较String时,equals和==的结果不同的原因,因为String重写了equals,地址相同或者对象中的内容相同就会返回true,假如没有重写,那么equals和==就没有区别。一般其他的一些类都有重写。
4、一般当你重写了equals方法时需要重写hashcode方法,因为当重写后对象相等后,需要满足hashcode值也相等。不然当你将数据存储到hashset中时就会出现问题,hashset中的值是不能重复的,就是根据对象的hashcode的值判断的,如果只重写equals 不重写hashcode可能造成相同的对象有不同的hashcode值(不重写就是比较地址的哈希码,然而改变了就需要根据需求改变),就可能重复存储。
以上是关于是每个JAVA对象都对应一个自己的HASHCODE吗?的主要内容,如果未能解决你的问题,请参考以下文章