zoukankan      html  css  js  c++  java
  • 第9条:覆盖equals时总是覆盖hashCode

    在每个覆盖equals方法的类中,也必须覆盖hashCode方法。否则,会违反Object.hashCode的通用约定,从而导致该类无法结合所有基于散列的集合一起正常工作,包括HashMap,HashSet,Hashtbale。

    下面我们先看下hashCode约定内容:

      1.只要对象equals方法的比较操作所用到的信息没有被修改,对同一对象调用多次,hashCode方法都必须返回同一整数。在同一应用程序的多次执行过程中,每次执行返回的整数可以不一致。

      2.如果两个对象根据equals(Object)方法比较是相等的,那么这两个对象的hashCode返回值相同。

      3.如果两个对象根据equals(Object)方法比较是不等的,那么这两个对象的hashCode返回值不一定不等,但是给不同的对象产生截然不同的整数结果,能提高散列表的性能。

    如果不覆盖hashCode方法,我们在需要用到hashCode的地方可能不会如我们所愿,下面看个例子,有这么一个类,我们只覆盖了equals方法,没有覆盖hashCode方法:

    class MyObject{
        private String field01;
    
        public MyObject(String field01) {
            this.field01 = field01;
        }
        
        //覆盖equals方法
        @Override
        public boolean equals(Object o) {    
            if (this == o) return true;
            if (o == null || getClass() != o.getClass())
                    return false;
            MyObject myObject = (MyObject) o;
            return (field01 == null ? myObject.field01 == null : field01.equals(myObject.field01));
        }
    }
    
    public class EffictiveTest {
        public static void main(String[] args) {
              Map<MyObject, String> map = new HashMap<>();
              map.put(new MyObject("123"), "123");
              System.out.println(map.get(new MyObject("123")));
        }
    }

    通过运行的结果我们可以看到key是new MyObject("123")时,value是null,从而我们知道即使覆盖了equals方法后还是不能保证相等,原因在于该类违反了hashCode的约定,由于MyObject没有覆盖hashCode方法,导致两个相等的实例拥有不相等的散列码,put方法把此对象放在一个散列桶中,get方法从另外一个散列桶中查找这个对象,这显然是无法找到的。

      

    当我们加入hashCode方法后就正确显示结果了。

    //至于hashCode方法怎么写,返回的哈希值参考是什么,可以参考:http://blog.csdn.net/zuiwuyuan/article/details/40340355
    @Override
    public int hashCode() {
         int result = field01.hashCode() * 17;
         return result;
    }

      

    作者:哀&RT
    出处:博客园哀&RT的技术博客--http://www.cnblogs.com/Tony-Anne/
    您的支持是对博主最大的鼓励,感谢您的认真阅读。
    本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    OpenGL模板缓冲区与模板测试
    u3d调用c++ dll的DllNotFoundExceion 问题
    u3d调用自己的dll
    使用 idea 的Bookmarks(书签)功能
    maven 相关问题
    项目
    使用 vi/vim 时,粘贴进新创建文件或空文件的首行内容丢失的解决方法
    Thread.sleep还是TimeUnit.SECONDS.sleep
    搭建 Guacamole 并解决各种坑和创建不了虚拟驱动器导致无法实现文件传输的方法
    properJavaRDP 跑通本地远程桌面
  • 原文地址:https://www.cnblogs.com/Tony-Anne/p/6727671.html
Copyright © 2011-2022 走看看