一致性
即如果两个对象相等的话,那么它们必须始终保持相等,除非至少有一个对象被修改了。
在Object类equals函数的说明中的最后一段提到当我们改写equals函数的时候,通常都需要改写hashCode函数,后者同样在Object类中进行了定义,hashCode()函数返回一个对象的散列值(hash code),在java中有些集合类都是基于散列值的,如HashMap、HashSet、Hashtable等;它们都根据对象的散列值将其映射到相应的散列桶中。如Hashtable的put和get函数的实现如下所示:
- public synchronized V get(Object key) {
- Entry tab[] = table;
- int hash = key.hashCode();
- int index = (hash & 0x7FFFFFFF) % tab.length;
- for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
- if ((e.hash == hash) && e.key.equals(key)) {
- return e.value;
- }
- }
- return null;
- }
-
- ublic synchronized V put(K key, V value) {
-
- if (value == null) {
- throw new NullPointerException();
- }
-
-
- Entry tab[] = table;
- int hash = key.hashCode();
- int index = (hash & 0x7FFFFFFF) % tab.length;
- for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
- if ((e.hash == hash) && e.key.equals(key)) {
- V old = e.value;
- e.value = value;
- return old;
- }
- }
-
- modCount++;
- if (count >= threshold) {
-
- rehash();
-
- tab = table;
- index = (hash & 0x7FFFFFFF) % tab.length;
- }
-
-
- Entry<K,V> e = tab[index];
- tab[index] = new Entry<K,V>(hash, key, value, e);
- count++;
- return null;
- }
因而hashCode函数极大地影响了这些集合类的正常工作。如果在改写完equals函数后,不相应改写hashCode函数,则可能会得不到想要的结果。如下例所示:
- Point p1 = new Point(1, 2);
- Point p2 = new Point(1, 2);
- Hashtable<Point, String> ht = new Hashtable<Point, String>();
- ht.put(p1, "value");
- System.out.println(p1.equals(p2));
- 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()`方法是对象的基本组成部分,它们主要用于对象的比较和存储。这两个方法在`java.lang.Object`类中定义,因此所有的Java类都默认继承了这两个方法。然而,根据具体的应用...
在Java编程语言中,`equals()`方法和`==`运算符是两个经常被用来比较对象是否相等的关键概念。理解它们的区别对于编写出正确、健壮的代码至关重要。 首先,`==`运算符用于基本类型(如int, char, boolean)的比较,...
在Java语言中,equals()和hashCode()两个函数的使用是紧密配合的,你要是自己设计其中一个,就要设计另外一个。在多数情况下,这两个函数是不用考虑的,直接使用它们的默认设计就可以了。但是在一些情况下,这两个...
在Java编程语言中,`hashCode()` 和 `equals()` 是两个非常重要的方法,它们主要用于对象的比较和哈希表(如HashMap)的操作。标题提到的"HashCode相同equals不同的2位字符集合算法"涉及到的是一个特定场景:两个...
在Java编程语言中,`hashCode()`与`equals()`方法是非常重要的概念,它们不仅对于深入理解Java内存管理至关重要,也是实现自定义类的关键部分之一。本文将详细介绍这两个方法的工作原理、使用场景以及在Java集合框架...
深入理解Java中HashCode方法 Java中的hashCode方法是每个类都需要实现的重要方法之一,它的主要作用是将对象的数据转换为一个32位的整数,用于标识对象的唯一性。在Java的所有类中,Object类是最顶层的父类,它定义...
### set接口中hashCode和equals...在Java中,正确实现`hashCode`和`equals`方法对于确保`Set`接口的有效性和高性能至关重要。开发人员需要仔细设计这两个方法,以满足`Set`接口的要求,并考虑到性能和一致性等方面。
在Java编程中,`hashCode()`、`equals()`以及`==`是三个经常被提及的概念,它们在处理对象的比较和存储时起着关键作用。本文将深入探讨这三个概念的介绍、区别以及它们在Java对象比较中的应用。 首先,`hashCode()`...
### Java 高级特性详解 #### 一、`hashCode` ...正确地重写 `equals` 和 `hashCode` 方法、使用 `Comparator` 进行排序、利用反射机制和序列化技术,以及实现 `clone` 方法都是开发高质量 Java 应用程序的重要技能。
在Java编程语言中,`equals()` 和 `hashCode()` 方法是对象的基本组成部分,它们与对象的比较和哈希表(如 `HashMap`)的操作密切相关。在面试中,面试官提出的问题直指这两个方法的重要关联。 首先,`equals()` ...
在Java编程语言中,`equals()` 方法是一个关键的成员函数,它主要用于比较对象的值是否相等。这个方法源自于 `Object` 类,是所有其他类的基类。默认情况下,`equals()` 方法的行为与 `==` 运算符相同,即比较两个...
在采用哈希算法的集合中,hashCode 方法和 equals 方法是紧密相关的。hashCode 方法用于计算对象的哈希值,而 equals 方法用于判断两个对象是否相等。如果两个对象的哈希值相同,那么它们也应该是相等的,反之亦然。...
在Java编程语言中,`hashCode()`方法是`Object`类的一个重要成员,它用于生成对象的哈希码,这个哈希码是一个整数,通常用于优化基于哈希的集合操作,如`HashSet`、`HashMap`和`HashTable`。这些集合依赖于`hashCode...
Java HashMap是一种基于哈希表的数据结构,它的存储原理是通过将Key-Value对存储在一个数组中,每个数组元素是一个链表,链表中的每个元素是一个Entry对象,Entry对象包含了Key、Value和指向下一个Entry对象的引用。...
本主题将深入探讨如何利用反射技术绕过编译器的一些限制,并介绍hashcode在高级应用中的用法。 首先,让我们理解反射的基本概念。在Java中,反射提供了一种方式,使我们能够在运行时动态地获取类的信息(如类名、...
在Java编程语言中,`hashCode()`函数是一个非常关键的方法,特别是在使用哈希数据结构如HashMap、HashSet和Hashtable时。这个函数的主要目的是为了高效地定位对象在哈希表中的位置。当我们谈论哈希码,实际上是在...
在Java编程语言中,`equals()`方法是一个非常关键的成员函数,主要用于比较两个对象是否相等。这个方法在Java的Object类中定义,并且所有的Java类都默认继承了Object类,因此所有类的对象都可以使用`equals()`方法。...