zoukankan      html  css  js  c++  java
  • java基础解析系列(十一)---equals、==和hashcode方法

    java基础解析系列(十一)---equals、==和hashcode方法

    目录

    ==

    • 基本数据类型==比较的是值
    类型 字节数
    float 4
    double 8
    byte 1
    short 2
    int 4
    long 8
    char 2
    boolean
    • 非基本数据类型,也就是引用型变量,==比较的是指向的内存地址

    equals

    • Object类的的equals方法内部是用==比较,也就是比较地址
    public boolean equals(Object obj) {
            return (this == obj);
        }
    
    • 而如果不同类会重写equals方法,比如String内部的equals比较的字符串的内容是否一样
    public boolean equals(Object anObject) {
            if (this == anObject) {
                return true;
            }
            if (anObject instanceof String) {
                String anotherString = (String)anObject;
                int n = value.length;
                if (n == anotherString.value.length) {
                    char v1[] = value;
                    char v2[] = anotherString.value;
                    int i = 0;
                    while (n-- != 0) {
                        if (v1[i] != v2[i])
                            return false;
                        i++;
                    }
                    return true;
                }
            }
            return false;
        }
    

    hashcode方法

    作用

    • 如果没有hashcode方法,在往一个set(不允许重复)添加的元素的时候,那么就得将全部的元素检查一遍equals,如果有hashcode方法,一个对象的hashcode会映射到一个位置,在这个位置检查是否存在即可,所以不需要全部检查。可以看看hashmap的put方法
    public V put(K key, V value) {
            if (key == null)
                return putForNullKey(value);
            int hash = hash(key.hashCode());
            int i = indexFor(hash, table.length);
            for (Entry<K,V> e = table[i]; e != null; e = e.next) {
                Object k;
                if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                    V oldValue = e.value;
                    e.value = value;
                    e.recordAccess(this);
                    return oldValue;
                }
            }
     
            modCount++;
            addEntry(hash, key, value, i);
            return null;
        }
    
    • 从源码可以看到,先通过hash值找到在table中的位置,然后再进行查找,这样就减少了执行equals的次数

    equals方法和hashcode方法

    • equals方法返回true,hashcode一定相同
    • equals方法返回flase,hahscoe不一定不同

    修改了equals方法

    • 前面已经了解过,Object的equals返回两个对象的内存地址是否相同,而Object类的子类经常会重写equals方法,比如两个People对象,比较的不是两个People对象的内存地址,而是比较name,age等属性,只要name和age相同就认为是同一个对象
    • 如果只重写了equals而不重写hashcode方法,下面进行测试
    public static void main(String[] args) throws Exception {
            HashMap hashMap=new HashMap<Person,Integer>();
            Person p1=new Person("jiajun",18);
            Person p2=new Person("jiajun",18);
            System.out.println("这两个对象在设置的时候应该是相同的");
            hashMap.put(p1,666);
            System.out.println("那么按照我们的设计思路,我们通过p2应该可以得到666");
            System.out.println(hashMap.get(p2));
            System.out.println("可是这时候输出的却是null");
    }
    class Person
    {
        String name;
        int age;
        public Person(String name,int age)
        {
            this.name=name;
            this.age=age;
        }
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if(this.getClass()!=obj.getClass())
            {
                return false;
            }
            People p = (People)obj;
            return this.name.equals(p.name)
                    && this.age == p.age;
        }
    
    }
    
    • 从实验结果可以看出,如果重写了equals方法而不重写hashcode方法容易出现问题

    Effective java的建议

    • 在程序执行期间,只要equals方法的比较操作用到的信息没有被修改,那么对这同一个对象调用多次,hashCode方法必须始终如一地返回同一个整数
    • 如果两个对象进行equals比较是相等的,那么这两个对象的hashcode方法必须返回相同的整数结果
    • 如果两个对象进行equals比较是不同的,那么这个两个对象hahscode方法不一定返回不同的整数

    我觉得分享是一种精神,分享是我的乐趣所在,不是说我觉得我讲得一定是对的,我讲得可能很多是不对的,但是我希望我讲的东西是我人生的体验和思考,是给很多人反思,也许给你一秒钟、半秒钟,哪怕说一句话有点道理,引发自己内心的感触,这就是我最大的价值。(这是我喜欢的一句话,也是我写博客的初衷)

    作者:jiajun 出处: http://www.cnblogs.com/-new/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。如果觉得还有帮助的话,可以点一下右下角的【推荐】,希望能够持续的为大家带来好的技术文章!想跟我一起进步么?那就【关注】我吧。

  • 相关阅读:
    C# Distinct去重泛型List
    分布式高并发系统如何保证对外接口的幂等性?转载
    描述文件安装失败:Please ensure the provisioning profile is configured for this device. If not, please try to generate
    Java基础-概述
    Java基础-语法
    使用 Proxifier + Charles 抓取本机 Http请求 /
    Git回退服务器版本及receive.denyDeleteCurrent配置
    codeforces#1549D. Integers Have Friends
    NOI 2021 ~Last Celebration~
    docker
  • 原文地址:https://www.cnblogs.com/-new/p/7792170.html
Copyright © 2011-2022 走看看