Set
Set 注重独一无二的性质,该体系集合用于存储无序(存入和取出的顺序不一定相同)元素,值不能重复。
set的继承关系
从上图可以清晰看到,Java Set 的实现类有TreeSet, HashSet , LinkedHashSet.
1. HashSet
HashSet:基于哈希表实现,支持快速查找,查找速度O(1),但不支持有序性操作。并且失去了元素的插入顺序信息,也就是说使用 Iterator 遍历 HashSet 得到的结果是不确定的。
哈希表是什么? 简单可以看成一个特殊的数组
根据百度百科解释:
散列表(Hash table,也叫哈希表),是根据键(Key)而直接访问在内存存储位置的数据结构。也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做散列函数,存放记录的数组称做散列表。
1.1底层实现(以jdk1.8为例)
通过查看HashSet底层源码,我们可以找到这么一段注释
/**
* This class implements the <tt>Set</tt> interface, backed by a hash table
* (actually a <tt>HashMap</tt> instance). It makes no guarantees as to the
* iteration order of the set; in particular, it does not guarantee that the
* order will remain constant over time. This class permits the <tt>null</tt>
* element.
简单翻译一下
hashSet 继承与Set, 同时是通过哈希表实现的,不能保证每次的迭代顺序一致,本质上它是一个HashMap,同时它允许空值。这与我们之前说的大体一致。
底层实现
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
static final long serialVersionUID = -5024744406713321676L;
private transient HashMap<E,Object> map;
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
/**
* Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
* default initial capacity (16) and load factor (0.75).
*/
public HashSet() {
map = new HashMap<>();
}
/**
* Constructs a new set containing the elements in the specified
* collection. The <tt>HashMap</tt> is created with default load factor
* (0.75) and an initial capacity sufficient to contain the elements in
* the specified collection.
*
* @param c the collection whose elements are to be placed into this set
* @throws NullPointerException if the specified collection is null
*/
public HashSet(Collection<? extends E> c) {
map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c);
}
2. TreeSet
TreeSet:基于红黑树实现,支持有序性操作,例如根据一个范围查找元素的操作。但是查找效率不如 HashSet,TreeSet 查找速度时间复杂度为 O(logN)。
红黑树是什么?
红黑树是一棵二叉搜索树(ALV),它在每个节点增加了一个存储位记录节点的颜色,可以是红,也可以是黑;通过任意一条从根到叶子简单路径上颜色的约束,红黑树保证最长路径不超过最短路径的二倍,因而近似平衡。
3. LinkedHashSet
对于 LinkedHashSet 而言,具有 HashSet 的查找效率,并且内部使用双向链表维护元素的插入顺序。其插入顺序是可以预知的。同时继承于HashSet
感谢阅读!
ps: 我本来想深入写一下Set底层的实现,结果发现这些实现类都和Map 有关系,想想还是留着下次写Map在写吧,现在就简单概括一下吧╮(╯▽╰)╭