• 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可能会碰撞。

  • 相关阅读:
    01背包
    manacher马拉车算法
    盒子放球的DP
    Children’s Queue
    抽象类_作为接口
    斯特林数
    欧拉路HDU3018
    2019 SDN上机第三次作业
    第05组 Alpha冲刺(2/4)
    Alpha冲刺(1/4)
  • 原文地址:https://www.cnblogs.com/fubaizhaizhuren/p/5104842.html
Copyright © 2020-2023  润新知