zoukankan      html  css  js  c++  java
  • Java之hashCode的作用和equals方法的重构规则

    这个是博主对hashcode的初步理解,以后加深了会再来更新:

    1、hashcode是什么?

    hashcode是对象的散列码,不同的对象几乎不一样,说几乎是因为还是可以一样的。

    特点:每一个对象都有hashcode,默认的值是每一个对象的地址。

    2、hashcode的作用:

    博主已知的方便用户使用散列表插入数据,我们知道,集合有两种,list----可重复,set----不可重复。

    其中set实现不可重复就需要使用到hashcode和equals方法。

    散列表set是使用链表数组实现的,每一个列表被称作桶,而查找表中对象的位置使用的方法是:

    1)、计算对象的散列码hashcode;

    2)、公式:hashcode%桶数=索引;eg:某一个对象的散列码是76268,有128个桶,那么对应的这个对象的位置就是在第108个桶中。

    而在插入对象到散列表中的时候使用的是同样的过程,只是这个时候可能会发现原有的位置被占用了,桶已经满了,这个时候就需要equals方法进行判断是否相等。

    所以:

    在重构equals方法的时候一定要重构hashcode方法,不然使用散列表的时候桶都找不到,更不用说下一步的判断是否是同一个对象了。

    下面是示例代码:

        public static void main(String[] args) {
            String hello = "hello";
            StringBuilder helloSB = new StringBuilder(hello);
    
            String hello2 = "hello";
            StringBuilder hello2SB = new StringBuilder(hello2);
    
            System.out.println("hello's hashcode:" + hello.hashCode());
            System.out.println("helloSB's hashcode:" + helloSB.hashCode());
            System.out.println("hello2's hashcode:" + hello2.hashCode());
            System.out.println("hello2SB's hashcode:" + hello2SB.hashCode());
    
    
            Set stringSet = new HashSet();
            Set sbSet = new HashSet();
    
            stringSet.add(hello);
            System.out.println("======" + stringSet.contains(hello2));
            stringSet.add(hello2);
    
    
            sbSet.add(helloSB);
            sbSet.add(hello2SB);
    
    
            Person person1 = new Person(1, "eke");
            Person person2 = new Person(1, "eke");
    
            Set personSet = new HashSet();
    
            personSet.add(person1);
            personSet.add(person2);
    
    
            PersonWithHashCode code1 = new PersonWithHashCode(1, "eke");
            PersonWithHashCode code2 = new PersonWithHashCode(1, "eke");
    
            Set codeSet = new HashSet();
    
            codeSet.add(code1);
            codeSet.add(code2);
    
            System.out.println(stringSet.size());
            System.out.println(sbSet.size());
            System.out.println(personSet.size());
            System.out.println(codeSet.size());
        }
    

    运行结果:  

    hello's hashcode:99162322
    helloSB's hashcode:39219479
    hello2's hashcode:99162322
    hello2SB's hashcode:2031787571
    ======true
    1
    2
    2
    1
    

      

    下面是PersonWithHashCode,Person和PersonWithHashCode相比只是缺少了hashCode方法。 

     贴这个代码还有一点是重构了equals方法,这个方法的重构是要遵循一定规则的(图片来自《java核心技术卷II》):

    public class PersonWithHashCode {
        private int id;
        private String name;
    
        public PersonWithHashCode(int id, String name) {
            this.id = id;
            this.name = name;
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public int hashCode() {
            return id * 24 + name.hashCode();
        }
    
        @Override
        public boolean equals(Object object) {
            if (object == this)
                return true;
    
            if (object == null)
                return false;
    
            if (getClass() != object.getClass())
                return false;
    
            PersonWithHashCode person = (PersonWithHashCode) object;
            return this.id == person.id
                    && Person.StringUtils.compare(name, person.getName());
        }
    
        static class StringUtils {
            static boolean compare(String a, String b) {
                if (a == null && b == null)
                    return true;
    
                if (a == null && b != null) {
                    return false;
                }
    
                if (a != null && b == null)
                    return false;
    
                return a.equals(b);
            }
    
        }
    
    }
    

      

  • 相关阅读:
    visual studio项目多级引用不拷贝dll的问题
    ef6 code first,对已有数据库如何执行迁移
    wsl 修改默认安装路径
    Windows docker镜像文件无法删除
    Docker镜像下载很慢,各种加速无效
    activemq整合springboot使用(个人微信小程序用)
    angular入门一之环境安装及项目创建
    jquery中attr()和prop()的区别
    IntelliJ IDEA部署web项目,Tomcat没有出现Artifacts
    IntelliJ IDEA:创建Java Web工程
  • 原文地址:https://www.cnblogs.com/heisehenbai/p/8028649.html
Copyright © 2011-2022 走看看