JavaSE Set集合
目录
Set 集合是什么?有什么用?
Set 集合类似于一个罐子,对于加入集合的元素,集合通常不能记住元素的添加顺序。
Set 集合与 Collection 集合基本相同,没有提供任何额外的方法。不同在于,Set 集合不允许包含重复元素。
Set 集合和 Map 集合关系密切,HashSet 底层是 HashMap,LinkedHashSet 底层是 LinkedHashMap,TreeSet 底层是 TreeMap。
返回目录
Set 集合怎么用?
1 Set 集合的继承图(常用部分)
返回目录
2 Set 接口
Set 接口是 Collection 接口的子接口,没有提供任何额外的方法。
public interface Set<E> extends Collection<E> {
...
boolean add(E e);
boolean addAll(Collection<? extends E> c);
boolean remove(Object o);
boolean removeAll(Collection<?> c);
void clear();
boolean retainAll(Collection<?> c);
boolean contains(Object o);
boolean containsAll(Collection<?> c);
int size();
boolean isEmpty();
...
}
返回目录
3 HashSet 类
-
3-1 介绍 HashSet 类实现了 Set 接口。HashSet 的底层是 HashMap。 HashSet 是线程不安全的。 HashSet 的元素可以为 null,但是只能有一个。 HashSet 不能保证元素的顺序。 HashSet 根据元素的 hashCode,将其添加到数组的特定位置上。通过 equals 方法判断两个元素是否相等。
返回目录
-
3-2 底层结构 HashSet 的底层是 HashMap。HashSet 的元素保存在 key 上,value 上用一个空值 PRESENT 占位。 (1)HashMap 底层是数组+链表的数据结构。 数组是 Node[] table,数组的每个位置上,存放着 Node 节点,该节点可以指向下一个 Node节点,从而形成链表。 (2)k-v 包装在 Node 类中,该类是 HashMap 的内部类。
public class HashSet<E>...{
...
private transient HashMap<E,Object> map;
private static final Object PRESENT = new Object();
public HashSet() {
map = new HashMap<>();
}
public HashSet(int initialCapacity) {
map = new HashMap<>(initialCapacity);
}
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<>(initialCapacity, loadFactor);
}
...
}
返回目录
-
3-3 扩容机制 与 HashMap 的扩容机制一样。
public class HashSet<E>...{
...
private transient HashMap<E,Object> map;
private static final Object PRESENT = new Object();
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
...
}
返回目录
返回目录
4 LinkedHashSet 类
-
4-1 介绍 LinkedHashSet 是 HasSeth 的子类。LinkedHashSet 底层是 LinkedHashMap。 HashSet 是无序的,即它不能保证元素的迭代顺序和插入顺序一致。 而 LinkedHashSet 可以保证元素的迭代顺序和插入顺序一致。
返回目录
public class LinkedHashSet<E> extends HashSet<E>...{
...
public LinkedHashSet() {
super(16, .75f, true);
}
public LinkedHashSet(int initialCapacity) {
super(initialCapacity, .75f, true);
}
public LinkedHashSet(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor, true);
}
...
}
public class HashSet<E>...{
...
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
...
}
返回目录
-
4-3 扩容机制 和 LinkedHashMap 一样。
返回目录
返回目录
5 TreeSet 类
返回目录
-
5-2 底层结构 TreeSet 底层是 TreeMap。
public class TreeSet<E>...{
...
private transient NavigableMap<E,Object> m;
private static final Object PRESENT = new Object();
public TreeSet() {
this(new TreeMap<E,Object>());
}
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator));
}
...
}
返回目录
返回目录
6 不同 Set 集合的使用场景
HashSet:允许元素无序时使用。
LinkedhashSet:需要元素的取出顺序和插入顺序一致时使用。
TreeSet:需要对元素进行排序时使用。
返回目录
|