关于HashSet 的hashCode重写问题记录心得

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_38361347/article/details/82320873

HashSet的的的特点:

不重复,无序,相对于TreeSet中的中的速度快等特点。

废话不多说先看一组代码,然后在总结原因!

首先

新建Stu(POJO)并且重写的的的toString()方法

public class Stu {

	
	private int age;
	private String name;
	public Stu(int age, String name) {
		this.age = age;
		this.name = name;
	}
	@Override
	public String toString() {
		return "Stu [age=" + age + ", name=" + name + "]";
	}
	
	
}

其次

	Set<Object> s = new HashSet<>();
		
		s.add(new Stu(1, "zs"));
		s.add(new Stu(1, "zs"));
		s.add(new Stu(2, "zs"));

		s.add(new Stu(2, "zs"));
		s.add(new Stu(3, "zs"));

		s.forEach(stu -> {
			
				System.err.println(stu );
			
		});

输出先看结果

怎么会有重复的呢?HashSet的中的默认不是不是重复的?怎么回事?

再来看一组实例,我们往里面添加一组字符串。

        s.clear();		
        s.add( "zs1");
		s.add("zs1");
		s.add("zs2");
		s.add( "zs2");
		s.add( "zs3");
		

输出结果

为什么存储一个Stu对象可以重复?添加字符串的不重复呢?

原因在于

查看字符串源码你会发现,字符串重写了的的的HashCode()方法

而Stu类并没有实现的的的HashCode()方法

HashSet的中的底层是通过哈希表而确定是不是重复的,哈希值唯一,所以进行添加元素的,而Stu中并并有实现这个方法!

我们打印出他的的的的的hashCode值

Stu的hashCode值不一样,但是存在相同的对象值。

默认Java中所有类的顶级父类的object对象如果没有继承的关系的话,一个类会默认继承 object 对象类,所以对象类中的hashCode()方法方法并没有被重写,所以导致的原因是Stu添加到HashSet的中的中是重复!

重写Stu的hashCode()方法

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}
	

重写添加并输出(这次没有重复)

另外:equals 等于也是默认继承对象的。

如果没有重写equals方法默认是按照对象对象的等于方法进行比较

object对象equals源码

==是比较内存地址的。

HashSet中的集合存放那个对象或者元素时一定查看是不是已经覆盖过的的hashCode方法,若没有请覆盖​​,若是字符串或者其他已经覆盖方法的则大胆使用!

猜你喜欢

转载自blog.csdn.net/weixin_38361347/article/details/82320873