1.特点:
元素无序且不可重复
两个特点的本质都是因为Set是基于Map集合实现的:
将元素作为key存储,key不可重复且key值是由hashcode
决定。
- Set集合,基础自Collection。特征是插入无序,不可指定位置访问。
- Set集合的实现类可说是基于Map集合去写的。通过内部封装Map集合来实现的比如
HashSet
内部封装了HashMap
。 - Set集合的数据库不能重复(== 或
eqauls
)的元素 - Set集合的常用实现类有
HashSet LinkedHashSet TreeSet
- 三个子类直接创建出来的是线程不安全的,想要创建线程安全的set可以通过工具类或者是juc包下相关的类创建。
CopyOnWriteArraySet
Collections.synchronizedSet(new HashSet<>());
- 三个子类直接创建出来的是线程不安全的,想要创建线程安全的set可以通过工具类或者是juc包下相关的类创建。
2.实现类
HashSet
底层是通过HashMap
实现的,各种方法底层也是HashMap
的方法
----》so不是线程安全的
通过无参构造方法可知:
public HashSet() {
map = new HashMap<>();
}
主要方法:
1)add
public boolean add(E e) {
return map.put(e, PRESENT)==null; //PRESENT始终是一个空值
}
将元素作为key存储,这也是为什么Set元素无序,不重复,不为null的原因
2)remove
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
3)遍历
key不能直接得到
要通过迭代器或者foreach遍历(本质也是迭代器)
LinkedHashSet
(1)LinkedHashSet
的底层使用LinkedHashMap
存储元素。
(2)LinkedHashSet
是有序的,它是按照插入的顺序排序的。
LinkedHashSet
源码只有四个构造方法和一个迭代器方法
public class LinkedHashSet<E>
extends HashSet<E>//继承HashSet
implements Set<E>, Cloneable, java.io.Serializable {
看下无参构造方法
public LinkedHashSet() {
super(16, .75f, true);//初始容量,加载因子
}
//super方法是
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
public LinkedHashMap(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor);
accessOrder = false;//不支持随机访问
}
LinkedHashSet继承自HashSet,它的添加、删除、查询等方法都是直接用的HashSet的,唯一的不同就是它使用LinkedHashMap存储元素。
TreeSet
TreeSet实现了SortedSet接口,它是一个有序的集合类,TreeSet的底层是通过TreeMap实现的。这里的有序是指**值的有序,不是存储有序。**TreeSet也支持两种排序方式:
自然排序
自定义排序
总结:
三个子类底层都是map集合实现的,
Hashset----HashMap
LinkedHashSet—LinkedHashMap
TreeSet----TreeMap