美文网首页
如果不实现hashCode()和equals()方法,会怎样?

如果不实现hashCode()和equals()方法,会怎样?

作者: 袁小象 | 来源:发表于2019-07-11 18:51 被阅读0次

    Object中的equals( )方法是去比较两个对象是不是同一个对象,即比较两个对象的地址是不是相等。是的话返回true。hashCode( )方法则是返回对象的内部地址表示。

    当我们自己实现一个类,但是没有实现这两个方法的话,会出现什么情况?

    一、首先明确这两个方法在HashMap中的意义:

    1、hashCode( ):
    当我们执行put( )操作时,主要用来确定key需要被存放到哪个slot(即hash桶)
    当我们执行get( )操作时,主要用来确定key被存放的slot(即hash桶)
    2、equals( ):

    • 当我们执行put( )操作时且已经确定了key的slot,如果slot中已经存了一些keys,则需要去遍历这些keys,如果有一个key和要put的key相等(equals返回true),则会替换旧值。
    • 当我们执行get( )操作时且已经确定了key的slot,对于该slot中已经存的keys进行遍历,如果hash值相等且equals返回true,则该key就是我们要找的。

    二、如果class没实现hashCode( )方法,会怎样?

    每次存放对象时,用该对象的地址作为hashCode去定位slot,貌似不会产生问题,但是有可能会因为hash值的分散性不够好,导致一个slot中插入过多的keys。
    而且对于原本相等的两个对象,有可能因为hash值不等,放在了两个不同的slot中。

    三、如果class没实现equals( )方法,会怎样?

    当我们连续put两个看上去相等的对象时(但是equals返回false),第二次put原本是打算修改第一个put时的value值,但是两次put插入了两个key,也就是说并没有覆盖第一个key的value。
    当我们用一个对象去get( )时,所使用的对象看似和想要获取的对象相等,实际上equals返回false。会返回null,或者得到的根本不是自己想要的。

    四、只实现hashCode,没实现equals

    static class People {
    
        private String name;
    
        private int age;
    
        public People(String name, int age) {
    
            this.name = name;
    
            this.age = age;
    
        }
    
        /*@Override
    
        public boolean equals(Object o) {
    
            if (this == o) return true;
    
            if (o == null || getClass() != o.getClass()) return false;
    
            People people = (People) o;
    
            return age == people.age &&
    
                    Objects.equals(name, [people.name](http://people.name));
    
        }*/
    
        @Override
    
        public int hashCode() {
    
            return Objects.hash(name, age);
    
        }
    
        @Override
    
        public String toString() {
    
            return "People{" +
    
                    "name='" + name + '\'' +
    
                    ", age=" + age +
    
                    '}';
    
        }
    
    }
    
    public void main() {
    
        Map<People, String> peopleMap = new HashMap<>();
    
        People zhangsan = new People("zhangsan", 21);
    
        People zhangsan2 = new People("zhangsan", 21);
    
        peopleMap.put(zhangsan, "zhangsan");
    
        peopleMap.put(zhangsan2, "zhangsan2");
    
        for (Map.Entry<People, String> entry : peopleMap.entrySet()) {
    
            System.out.println(entry.getKey() + ": " + peopleMap.get(entry.getKey()));
    
        }
    
    }
    /*
    输出:People{name='zhangsan', age=21}: zhangsan
    
         People{name='zhangsan', age=21}: zhangsan2
    
    分析:本来想等的两个object:o1和o2,o1.hashCode( ) == o2.hashCode( ),但是o1.equals( ) != o2.equals( ),
    
    这时,第一个v1并没有被覆盖,map中实际存了两个key,o1和o2.
    */
    

    五、只实现equals,没实现hashCode

    static class People {
        private String name;
        private int age;
    
        public People(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            People people = (People) o;
            return age == people.age &&
                    Objects.equals(name, people.name);
        }
        /*
        @Override
        public int hashCode() {
    
            return Objects.hash(name, age);
        }*/
    
        @Override
        public String toString() {
            return "People{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    
    public void main() {
        Map<People, String> peopleMap = new HashMap<>();
        People zhangsan = new People("zhangsan", 21);
        People zhangsan2 = new People("zhangsan", 21);
    
        peopleMap.put(zhangsan, "zhangsan");
        peopleMap.put(zhangsan2, "zhangsan2");
        for (Map.Entry<People, String> entry : peopleMap.entrySet()) {
            System.out.println(entry.getKey() + ": " + peopleMap.get(entry.getKey()));
        }
    }
    /*
    输出:People{name='zhangsan', age=21}: zhangsan
         People{name='zhangsan', age=21}: zhangsan2
    
    两个对象虽然相等,但是hashCode返回的值不一样,导致两个对象被存放在了不同的slot中。所以也是存了两个。
    */
    

    当我们实现了equals时,必须要实现hashCode,

    https://stackoverflow.com/questions/2265503/why-do-i-need-to-override-the-equals-and-hashcode-methods-in-java

    相关文章

      网友评论

          本文标题:如果不实现hashCode()和equals()方法,会怎样?

          本文链接:https://www.haomeiwen.com/subject/pccjkctx.html