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

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 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 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 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 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()方法,会怎样?)