`
xifangyuhui
  • 浏览: 185812 次
  • 性别: 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

分享到:
评论

相关推荐

    equals 和 hashCode两者效果分析详解.docx

    原因是因为,在Java自带的容器HashMap和HashSet中, 都需同时要用到对象的hashCode()和equals()方法来进行判断,然后再插入删除元素,这点我们一会再谈。 那么我们还是单独来看hashCode(),为什么HashMap需要用到...

    探索equals()和hashCode()方法_动力节点Java学院整理

    equals():反映的是对象或变量具体的值,即两个对象里面包含的值--可能是对象的引用,也可能是值类型的值。 hashCode():计算出对象实例的哈希码,并返回哈希码,又称为散列函数。根类Object的hashCode()方法的...

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

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

    Java synchronized详细解读.docx

    synchronized关键字可以作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块。如果 再细的分类,synchronized可作用于instance变量、object reference(对象引用)、static函数和class ...

    Lombok(Java库)

    @EqualsAndHashCode:自动生成 equals 和 hashCode 方法,用于对象的比较和哈希处理。 @NoArgsConstructor / @RequiredArgsConstructor / @AllArgsConstructor:自动生成构造函数。 @Data:整合了 @Getter、@...

    AIC的Java课程1-6章

    第9章 常用类 4课时  理解Object类及其常用方法equals,hashCode和finalize等。  能够使用String,StringBuffer,StringBuilder类创建字符串对象和使用其方法,分辨不同类之间的区别。 ...

    kassava:该库提供了一些有用的kotlin扩展函数,用于在没有所有样板的情况下实现toString(),hashCode()和equals()

    卡萨瓦 该库提供了一些有用的kotlin扩展函数,用于在没有所有样板的情况下实现toString() , equals()和hashCode() 。 该库的主要动机是用于无法使用数据类且需要通过以下方式实现toString() / equals() / hashCode...

    写给大忙人看的JAVA SE 8

    9.3 实现equals、hashCode和compareTo方法 198 9.3.1 安全的Null值相等测试 198 9.3.2 计算哈希码 199 9.3.3 比较数值类型对象 200 9.4 安全需要 201 9.5 其他改动 204 9.5.1 将字符串转换为数字 204 9.5.2 全局...

    Java基础知识点总结.docx

    equals()方法和hashCode()方法 270 数据结构 273 Array方法类汇总 304 Java数组与集合小结 305 递归 309 对象的序列化 310 Java两种线程类:Thread和Runnable 315 Java锁小结 321 java.util.concurrent.locks包下...

    疯狂JAVA讲义

    学生提问:Java为什么要对这些数据进行缓存呢? 67 3.7.6 逻辑运算符 67 3.7.7 三目运算符 68 3.7.8 运算符的结合性和优先级 69 3.8 本章小结 70 本章练习 70 第4章 流程控制和数组 71 4.1 顺序结构 72 4.2 ...

    Java常见面试题208道.docx

    3.两个对象的 hashCode()相同,则 equals()也一定为 true,对吗? 4.final 在 java 中有什么作用? 5.java 中的 Math.round(-1.5) 等于多少? 6.String 属于基础的数据类型吗? 7.java 中操作字符串都有哪些类?它们...

    Java核心技术II(第8版)

    10.4.5 远程对象与equals、hashCode和clone方法 10.5 远程对象激活 10.6 Web Services与JAX-WS 10.6.1 使用JAX-WS 10.6.2 Web服务的客户端 10.6.3 Amazon的E-Commerce服务 第十一章 脚本、编译与注解处理 11.1 Java...

    java8集合源码分析-Outline:大纲

    equals和hashcode(, ) string,stringbuffer和stringbuilder(,,,, ) 伪泛型(, , ) 自动装箱(,) Try-with-resources() 序列化 反序列化(, , , ) interface 和 abstract class 区别 变长参数( ) 枚举详解(, , , , ) ...

    java视频教程(52课)下 异常 IO 线程 类集框架 开发工具之Eclipse 综合练习

    44_equals函数的作用.mp4 45_hashCode()与toString().mp4 46_开发工具之Eclipse(一).mp4 47_开发工具之Eclipse(二).mp4 48_开发工具之Eclipse(三).mp4 49_开发工具之Eclipse(四).mp4 50_综合练习(一).mp4 51_综合...

    Poko:一个Kotlin编译器插件,用于对公共API中的数据类施加额外的关注

    像普通的Kotlin数据类一样,您所要做的就是在类的构造函数中提供成员。 然后为其提供@Poko批注,并享受生成的toString , equals和hashCode 。 (将添加针对Java使用者的Builder类和针对Kotlin使用者的DSL初始化器...

    去年秋招整理了这份后端开发的核心面试题(偏Java),顺利拿到了腾讯offer,决定把它贡献出来

    前言 2019年为了秋招,精挑细学了这一份面试题,并且只挑重点和难点,此次整理包括 Java、数据结构与算法、计算机网络、操作系统、数据库等。如果你能把这些面试题都...java中==和equals和hashCode的区别 int与integ

Global site tag (gtag.js) - Google Analytics