Set集合保证元素唯一
- Set集合底层数据结构是哈希表
- 实现唯一方法:
Set集合存储元素时会产生一个哈希值,是按照不同的哈希值进行存储的,首先用haseCode()方法获取一个int类型的哈希值,先比较哈希值是否相同,不同的话说明集合中还没有与之相同的元素,直接进行存储,相同的话再调用equals()方法判断内容是否完全一致,不相同的话在进行存储,简单来说就是:
1) ----hashCode()
不同:存储
2 )----相同:equals()
不同:存储
相同:不进行存储 - 先使用hashCode()方法比较哈希值而不是直接用equals()比较 提高了比较效率
- hashCode()与equals()底层源码:
public int hashCode() {
int h = 0;
Iterator<E> i = iterator();
while (i.hasNext()) {
E obj = i.next();
if (obj != null)
h += obj.hashCode();
}
return h;
}
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof Set))
return false;
Collection<?> c = (Collection<?>) o;
if (c.size() != size())
return false;
try {
return containsAll(c);
} catch (ClassCastException unused) {
return false;
} catch (NullPointerException unused) {
return false;
}
}
- Set集合存储自定义对象
(1)没有重写equals和hashCode方法
import java.util.HashSet;
import java.util.Set;
public class SetTest {
public static void main(String[] args) {
Set<Person> set=new HashSet<>();
set.add(new Person("贾宝玉",18));
set.add(new Person("林黛玉",16));
set.add(new Person("薛宝钗",20));
set.add(new Person("林黛玉",16));
set.add(new Person("林黛玉",17));
System.out.println("没有重写equals和hashCode方法");
for (Person person : set) {
System.out.println(person);
}
}
}
结果:
不重写equals和hashCode方法存储元素是不唯一的
(2)在自定义类中重写equals和hashCode方法
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
运行结果:
存储自定义对象要自己重写上述两个方法,而且只有内容完全不一样时才会不重复存储。