zoukankan      html  css  js  c++  java
  • hash-3.hashCode

    1、有一个类Person,有两个字段age和name,我重写Object类的equal方法来比较两个对象的age和name是否相等,
    但是不重写hashCode。

    package com.hash;
    
    public class Person {
        private Integer age;
        
        private String name;
        
        
    
        public Person() {
            super();
        }
        
        
        public Person(Integer age, String name) {
            super();
            this.age = age;
            this.name = name;
        }
    
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Person other = (Person) obj;
            if (age == null) {
                if (other.age != null)
                    return false;
            } else if (!age.equals(other.age))
                return false;
            if (name == null) {
                if (other.name != null)
                    return false;
            } else if (!name.equals(other.name))
                return false;
            return true;
        }
        
        
    }
    View Code

    场景类

    Person p1 = new Person(21,"tom");
    Person p2 = new Person(21,"tom");
    System.out.println(p1.equals(p2));

    这样比较发现打印出来是true。然后执行下面的代码:

    HashMap<Person,Integer> hp = new HashMap<Person,Integer>();
    hp.put(p1, 10);
    System.out.println(hp.get(p2));

    发现打印出来是null,原因分析:

    因这p1和p2只是逻辑上相等,但是它们的hashCode不相等,而hashMap往里面put对象的时
    候,先获取key的hashcode,再往hash表中存数据
    Person类没有重写hashCode方法,所以默认使用父类Object类的hashCode方法,是根据内存算的hashCode
    ,而p1和p2是在堆上new出的两个对象,二者的内存地址肯定不等,所以hashCode肯定不等,所以获取出来是null
    要解决这个问题,只有重写hashCode方法,以确保当两个对象相同时,二者的hashCode必须相同

        @Override
        public int hashCode(){
            Integer prime = 31;
            return prime*age.hashCode() + prime*name.hashCode();
        }

    重写hashCode方法后,再执行,发现打印出了10

    2、

    如果两个对象相同,那么二者hashCode必定相同,而hashCode相同,对象却不一定相同,因为散列函数计算hashCode的时候
    可能会发生碰撞,如

    hash类,我在这个类的hashCode方法里计算hashCode时,只是让age和name相加,这种hash算法,碰撞的机率非常大

    package com.hash;
    
    public class Hash {
        private Integer age ;
        
        private Integer name;
    
        public Hash(Integer age, Integer name) {
            super();
            this.age = age;
            this.name = name;
        }
    
        public Hash() {
            super();
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public Integer getName() {
            return name;
        }
    
        public void setName(Integer name) {
            this.name = name;
        }
    
        @Override
        public int hashCode() {
            final int prime = 31;
            return prime*age+prime*name;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Hash other = (Hash) obj;
            if (age == null) {
                if (other.age != null)
                    return false;
            } else if (!age.equals(other.age))
                return false;
            if (name == null) {
                if (other.name != null)
                    return false;
            } else if (!name.equals(other.name))
                return false;
            return true;
        }
        
        
    }
    View Code

    场景类

    //这就是hashCode产生碰撞,二者hashCode相同,而对象并不相等
            Hash ha1 = new Hash(11,12);
            Hash ha2 = new Hash(12,11);
            
            System.out.println(ha1.equals(ha2));
            System.out.println("h1 hashCode="+ha1.hashCode()+",h2 hashCode="+ha2.hashCode());

    虽然两个对象的hashCode相等,但是两个对象并不相等。

    综上

    (1)如果重写equal方法,则必须重写hashCode方法。

    (2)两个对象相等,则二者hashCode必然相等。

    (3)两个对象的hashCode相等,两个对象未必相等,因为计算的hashCode可能会碰撞。

  • 相关阅读:
    一句话解释c#中的特性,你了解多少
    CentOS虚拟机如何设置共享文件夹,并在Windows下映射网络驱动器?
    samba服务器配置及window网络磁盘映射
    PHP中各种Hash算法性能比较
    Redis持久化
    设置redis主从出现的问题
    Redis启动多端口、运行多实例
    Redis学习手册(主从复制)
    tengine/nginx-tomcat动静分离遇到的问题
    使用 Git Hooks 实现自动项目部署
  • 原文地址:https://www.cnblogs.com/fubaizhaizhuren/p/5104842.html
Copyright © 2011-2022 走看看