HashSet
HashSet是Set接口的实现类,和List集合一样都是隶属于Collection集合框架下的一个分支,也是日常开发中常用的集合类。
HashSet特点
- 保证集合中的元素不会重复
- 集合中的元素无序
这两点刚好和我们常用的ArrayList相反,ArrayList中的元素通常都是允许重复且有序的,从两个集合类的底层数据结构来看,就能明白为什么是这样了,ArrayList底层是数组,而HashSet底层实际上是HashMap来实现的,所以他们各自会有如上的特点。
构造方法
最常用的无参构造,默认创建了一个HashMap,赋值给了自己的成员变量,其他的几个无非就是自己设置一下Map容器的初始化容量大小或者加载因子等,这些都不重要,重点要当你new HashSet时,实际上内部new了一个HashMap。
public HashSet() {
map = new HashMap<>();
}
添加元素
HashSet有了之后,我们就可以条用add方法向集合中添加元素,那么当你调用add方法时实际上又是调用了map.put方法,key是你当前要添加到集合中的元素,value是一个Object对象,实际上这个value是什么值对于HashSet集合来说并不关心。
所以看完这个add方法就能解释,为什么set集合中的元素不会重复,且无序。因为元素都保存到了HashMap集合的key中,这是由HashMap集合的特性所决定的。
而map.put方法,如果返回值为null则表示要添加的key在map集合中不存在,所以对于set集合来说就表示添加成功,如果要添加的key在map集合中存在,put方法就会返回原来key的value值(对于HashSet来说都是PRESENT),所以map.put(e, PRESENT)==null就会返回false。
这些都是map相关的内容,如果还清楚,建议先看看map相关的实现原理 HashMap1.8源码深入分析,如果你已经非常了解HashMap了,那么再理解HashSet就太容易了。
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
删除元素
也是调用map.remove方法,根据返回值来判断
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
是否存在
public boolean contains(Object o) {
return map.containsKey(o);
}
遍历
public Iterator<E> iterator() {
return map.keySet().iterator();
}
当前容量
public int size() {
return map.size();
}
集合是否为空
public boolean isEmpty() {
return map.isEmpty();
}
清空
public void clear() {
map.clear();
}
总结
可以看到HashSet实际上所有的方法都是通过调用HashMap的方法来实现的,所以HashSet实际上就是一个只关心key值的HashMap容器而已。 (* ̄︶ ̄)