1  java类中HashSet添加对象时,为什么一定要重写equals方法和HasCode方法?

a  Set集合没有顺序,也不允许重复,为什么会这样?

答:是为了模拟现实的集合。

 

b  重复这里在现实中和内存中有什么区别?

答:现实中的重复指的是对象的重复,而内存中的重复指的hashCode的重复。

 

c  由于现实中和内存中的重复不同,存在一种情况,在内存中重复(hashCode)相同,现实中不是同一个对象,这种例子呢?

答:代码如下,debug可以看到两个person对象的hash码相同,其属性相同:

package com.array.set;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class TestHashSet2 {

    public static void main(String[] args) {

        Person p1 = new Person("a", 1);

        Person p2 = new Person("b", 0);

        Set<Person> set = new HashSet<Person>();

        set.add(p1);

        set.add(p2);

        Iterator<Person> it = set.iterator();

        while (it.hasNext()) {

            System.out.println(it.next().getName());

        }

    }

}

 

package com.array.set;

import java.util.HashSet;

import java.util.Iterator;

import java.util.Set;

class Person {

    private String name;

    private int id;

    Person(String name, int id) {

        this.name = name;

        this.id = id;

    }

    public void setName(String name) {

        this.name = name;

    }

    public String getName() {

        return name;

    }

    public void setId(int id) {

        this.id = id;

    }

    public int getId() {

        return id;

    }

    public int hashCode() {

        return name.hashCode() + id; // 使用字符串哈希值与Integer的哈希值的组合

        // 这样会产生重码,实际上重码率很高

    }

    public boolean equals(Object obj) {

        if (obj instanceof Person) { //

            Person p = (Person) obj;

            return (name.equals(p.name) && id == p.id);

        }

        return super.equals(obj);

    }

}

 

d  为了解决c这种情况(现实中的重复与内存的重复不一致),我们应该怎么做呢?

答:c代码已经给了明显的答案。

HashSet添加对象的时候,先用hashCode方法计算出该对象的哈希码。

比较:

        (1),如果该对象哈希码与集合已存在对象的哈希码不一致,则该对象没有与其他对象重复,添加到集合中!

        (2),如果存在于该对象相同的哈希码,那么通过equals方法判断两个哈希码相同的对象是否为同一对象(判断的标准是:属性是否相同)

                1>,相同对象,不添加。

                2>,不同对象,添加!

 

 

 

至此,1问题得到了解答。

  • 总思路:hashCode不同时,则必为不同对象。hashCode相同时,根据equlas()方法判断是否为同一对象。
  • 在HashSet,HashMap,HashTable中都存在该问题。

 

2  为什么重写Equals方法必须重写HashCode方法?

答:1、将要传入的数据根据系统的hash算法得到一个hash值;

  2、根据hash值可以得出该数据在hash表中的位置;

  3、判断该位置上是否有值,没有值则把数据插入进来;如果有值则再次判断传入的值与原值是否地址或equals相同,如果相同则不存,否则通过链表的方式 存储到该位置。

如果两个对象equals,但是没有重写hashcode,就会导致集合中可能存储多个相等的对象!所以必须重写!

 

引自:

https://jingyan.baidu.com/article/d5a880eb8fb61d13f147cc99.html

https://www.cnblogs.com/shew/p/11370804.html

 

posted on 2020-02-17 18:32  菜鸟乙  阅读(1230)  评论(0编辑  收藏  举报