zoukankan      html  css  js  c++  java
  • java中equals与hashCode的重写问题

    这几天有一个朋友问我在重写equals和hashCode上出现了问题,最后我帮她解决了问题,同时也整理出来分享给大家

    现上Object的equals与HashCode的代码

       public boolean equals(Object obj) {
            return (this == obj);
        }
       public native int hashCode();

    由上面可以看到Object的equlas方法等价于“==”,所以不能满足我们平时的需求,因此我们需要重写equals,在java中我们约定了重写equals的时候也要重写HashCode方法,可以参考String的equals与HashCode的方法,ok。。。上代码

     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;
        }
      public int hashCode() {
            int h = hash;
            if (h == 0 && value.length > 0) {
                char val[] = value;
    
                for (int i = 0; i < value.length; i++) {
                    h = 31 * h + val[i];
                }
                hash = h;
            }
            return h;
        }

    现在说说我对这两个方法的个人理解心得

    我们可以把HashCode理解为词典中的索引比如“词语”,“词典”两个词,所以当HashCode相同时,equals不一定相同,反过来equals相同。HashCode就一定相等,总结就是    equals相等,hashcode一定相等,equals不相等,hashcode不一定不相等(个人理解可能在某些问题上会有局限性)

    下面是是我自己重写的一个equals与HashCode的方法,具体问题都标注在代码中了

    public class Dog {
        public String name;
        public int age;
    
        public Dog(String name,int age){
            this.name=name;
            this.age=age;
        }
    
        @Override
        public boolean equals(Object obj) {
            if(this==obj) return true;
            /*第一个是通过比较地址来间接比较值的,毋庸置疑,如果地址是一样的话,那么值也是一样的。还有一点也能说明为什么是比较值而不是地址,
                那就是第一个判断只有返回true而没有返回false。因为如果是false的话那么说明地址是不同的,但是地址不同并不能说值不同,所以没
                有写返回false也说明了第一个是通过比较地址来间接比较值的,而不是只是简单的比较地址。*/
            if(this==null||(this.getClass()!=obj.getClass())) return false;
            /*if(!(obj instanceof Cat))  return false;  我在网上看到一些人这样写,这样写是不对的,当本类没有子类的时候可以,但是当本类
              存在子类会导致一些问题,======>>  a.equls(b) 返回true    b.equals(a) 返回false*/
            Dog dog=(Dog) obj;
            return this.age==dog.age&&this.name.equals(dog.name);
        }
    
        @Override
        public int hashCode() {
            return name.hashCode()*37+age;
        }
        public static void main(String[] args) {
            HashMap map=new HashMap();
            Dog d1=new Dog("x",1);
            Dog d2=new Dog("x",1);
            map.put(d1, 1);
            System.out.println(d1.equals(d2));             //=====>返回true
            System.out.println(map.get(new Dog("x",1)));  //=====>这里当补充些HashCode的时候的结果是null;只有在重写了HashCode才会出现结果"1"
    
        }
    }

     

  • 相关阅读:
    04--Spring知识汇总
    01--Java集合知识
    03-Servlet 体系结构知识梳理
    02--Tomcat总体结构分析一
    01--Java开发中文乱码问题分析
    HTTP05--HTML常用知识
    3--Java NIO基础1
    02--Java Socket编程--IO方式
    01--TCP状态转换
    java之泛型理解(高效java之泛型)
  • 原文地址:https://www.cnblogs.com/whiteme/p/7199558.html
Copyright © 2011-2022 走看看