`
xifangyuhui
  • 浏览: 189000 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

对java中equals和hashCode函数的一些理解2(转)

阅读更多

一致性 
即如果两个对象相等的话,那么它们必须始终保持相等,除非至少有一个对象被修改了。 

在Object类equals函数的说明中的最后一段提到当我们改写equals函数的时候,通常都需要改写hashCode函数,后者同样在Object类中进行了定义,hashCode()函数返回一个对象的散列值(hash code),在java中有些集合类都是基于散列值的,如HashMap、HashSet、Hashtable等;它们都根据对象的散列值将其映射到相应的散列桶中。如Hashtable的put和get函数的实现如下所示: 

Java代码
  1.   public synchronized V get(Object key) {  
  2. Entry tab[] = table;  
  3. int hash = key.hashCode();  
  4. int index = (hash & 0x7FFFFFFF) % tab.length;  
  5. for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {  
  6.     if ((e.hash == hash) && e.key.equals(key)) {  
  7.     return e.value;  
  8.     }  
  9. }  
  10. return null;  
  11.    }  
  12.   
  13. ublic synchronized V put(K key, V value) {  
  14. // Make sure the value is not null  
  15. if (value == null) {  
  16.     throw new NullPointerException();  
  17. }  
  18.   
  19. // Makes sure the key is not already in the hashtable.  
  20. Entry tab[] = table;  
  21. int hash = key.hashCode();  
  22. int index = (hash & 0x7FFFFFFF) % tab.length;  
  23. for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {  
  24.     if ((e.hash == hash) && e.key.equals(key)) {  
  25.     V old = e.value;  
  26.     e.value = value;  
  27.     return old;  
  28.     }  
  29. }  
  30.   
  31. modCount++;  
  32. if (count >= threshold) {  
  33.     // Rehash the table if the threshold is exceeded  
  34.     rehash();  
  35.   
  36.            tab = table;  
  37.            index = (hash & 0x7FFFFFFF) % tab.length;  
  38. }   
  39.   
  40. // Creates the new entry.  
  41. Entry<K,V> e = tab[index];  
  42. tab[index] = new Entry<K,V>(hash, key, value, e);  
  43. count++;  
  44. return null;  
  45.    }  

因而hashCode函数极大地影响了这些集合类的正常工作。如果在改写完equals函数后,不相应改写hashCode函数,则可能会得不到想要的结果。如下例所示: 
Java代码
  1. Point p1 = new Point(12);  
  2. Point p2 = new Point(12);  
  3. Hashtable<Point, String> ht = new Hashtable<Point, String>();  
  4. ht.put(p1, "value");  
  5. System.out.println(p1.equals(p2));  
  6. System.out.println(ht.get(p2));  

由上面Point类的实现,p1和p2是相等的,第一个语句正常输出true;但是第二个语句输出的值是null,并没有得到期望中的“value”。导致这一问题的根本原因是Point类改写了equals函数,对相等的概念作了更改,但没有相应更改hashCode函数,使得两个相等的函数拥有不同的hashCode,违反了Object类关于hashCode的约定中的第2点,从而返回了错误的结果。 
在Object类中定义的几个hashCode约定如下: 
1. 在同一应用中,一个对象的hashCode函数在equals函数没有更改的情况下,无论调用多少次,它都必须返回同一个整数。 
2. 两个对象如果调用equals函数是相等的话,那么调用hashCode函数一定会返回相同的整数。 
3. 两个对象如果调用equals函数是不相等的话,那么调用hashCode函数不要求一定返回不同的整数。 
我们在改写equals 和 hashCode 函数的时候,一定要遵守如上3条约定,在改写equals的同时也改写hashCode的实现,这样才能保证得到正确的结果。

转自:http://lionheart.iteye.com/blog/135077

分享到:
评论

相关推荐

    Java中的equals和hashCode方法详解1

    在Java编程语言中,`equals()`和`hashCode()`方法是对象的基本组成部分,它们主要用于对象的比较和存储。这两个方法在`java.lang.Object`类中定义,因此所有的Java类都默认继承了这两个方法。然而,根据具体的应用...

    java中equals()函数的用法 equals和==的区别

    在Java编程语言中,`equals()`方法和`==`运算符是两个经常被用来比较对象是否相等的关键概念。理解它们的区别对于编写出正确、健壮的代码至关重要。 首先,`==`运算符用于基本类型(如int, char, boolean)的比较,...

    解析Java对象的equals()和hashCode()的使用

    在Java语言中,equals()和hashCode()两个函数的使用是紧密配合的,你要是自己设计其中一个,就要设计另外一个。在多数情况下,这两个函数是不用考虑的,直接使用它们的默认设计就可以了。但是在一些情况下,这两个...

    HashCode相同equals不同的2位字符集合算法

    在Java编程语言中,`hashCode()` 和 `equals()` 是两个非常重要的方法,它们主要用于对象的比较和哈希表(如HashMap)的操作。标题提到的"HashCode相同equals不同的2位字符集合算法"涉及到的是一个特定场景:两个...

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

    在Java编程语言中,`hashCode()`与`equals()`方法是非常重要的概念,它们不仅对于深入理解Java内存管理至关重要,也是实现自定义类的关键部分之一。本文将详细介绍这两个方法的工作原理、使用场景以及在Java集合框架...

    深入理解Java中HashCode方法

    深入理解Java中HashCode方法 Java中的hashCode方法是每个类都需要实现的重要方法之一,它的主要作用是将对象的数据转换为一个32位的整数,用于标识对象的唯一性。在Java的所有类中,Object类是最顶层的父类,它定义...

    set接口经常用的hashCode和equals方法详解

    ### set接口中hashCode和equals...在Java中,正确实现`hashCode`和`equals`方法对于确保`Set`接口的有效性和高性能至关重要。开发人员需要仔细设计这两个方法,以满足`Set`接口的要求,并考虑到性能和一致性等方面。

    javahashcode()和equals()和==的介绍和区别.pdf

    在Java编程中,`hashCode()`、`equals()`以及`==`是三个经常被提及的概念,它们在处理对象的比较和存储时起着关键作用。本文将深入探讨这三个概念的介绍、区别以及它们在Java对象比较中的应用。 首先,`hashCode()`...

    JAVA_高级特性(hashCode,clone,比较器,Class反射,序列化)

    ### Java 高级特性详解 #### 一、`hashCode` ...正确地重写 `equals` 和 `hashCode` 方法、使用 `Comparator` 进行排序、利用反射机制和序列化技术,以及实现 `clone` 方法都是开发高质量 Java 应用程序的重要技能。

    面试官瞬间就饱了,重写equals函数,需要重写hashCode函数吗?

    在Java编程语言中,`equals()` 和 `hashCode()` 方法是对象的基本组成部分,它们与对象的比较和哈希表(如 `HashMap`)的操作密切相关。在面试中,面试官提出的问题直指这两个方法的重要关联。 首先,`equals()` ...

    java equals函数用法详解

    在Java编程语言中,`equals()` 方法是一个关键的成员函数,它主要用于比较对象的值是否相等。这个方法源自于 `Object` 类,是所有其他类的基类。默认情况下,`equals()` 方法的行为与 `==` 运算符相同,即比较两个...

    重写equals方法

    在采用哈希算法的集合中,hashCode 方法和 equals 方法是紧密相关的。hashCode 方法用于计算对象的哈希值,而 equals 方法用于判断两个对象是否相等。如果两个对象的哈希值相同,那么它们也应该是相等的,反之亦然。...

    浅谈Java中的hashcode方法(推荐)

    在Java编程语言中,`hashCode()`方法是`Object`类的一个重要成员,它用于生成对象的哈希码,这个哈希码是一个整数,通常用于优化基于哈希的集合操作,如`HashSet`、`HashMap`和`HashTable`。这些集合依赖于`hashCode...

    java HashMap原理分析

    Java HashMap是一种基于哈希表的数据结构,它的存储原理是通过将Key-Value对存储在一个数组中,每个数组元素是一个链表,链表中的每个元素是一个Entry对象,Entry对象包含了Key、Value和指向下一个Entry对象的引用。...

    利用反射绕过编译器和hashcode高级应用

    本主题将深入探讨如何利用反射技术绕过编译器的一些限制,并介绍hashcode在高级应用中的用法。 首先,让我们理解反射的基本概念。在Java中,反射提供了一种方式,使我们能够在运行时动态地获取类的信息(如类名、...

    详解Java中用于查找对象哈希码值的hashCode()函数

    在Java编程语言中,`hashCode()`函数是一个非常关键的方法,特别是在使用哈希数据结构如HashMap、HashSet和Hashtable时。这个函数的主要目的是为了高效地定位对象在哈希表中的位置。当我们谈论哈希码,实际上是在...

    Java 程序显示 equals() 方法的用法.docx

    在Java编程语言中,`equals()`方法是一个非常关键的成员函数,主要用于比较两个对象是否相等。这个方法在Java的Object类中定义,并且所有的Java类都默认继承了Object类,因此所有类的对象都可以使用`equals()`方法。...

Global site tag (gtag.js) - Google Analytics