版权声明:本文为博主原创文章,未经博主允许不得转载。 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方法,若没有请覆盖,若是字符串或者其他已经覆盖方法的则大胆使用!