原创不易,如需转载,请注明出处https://www.cnblogs.com/baixianlong/p/10703558.html,否则将追究法律责任!!!
底层实现,源码如下:
public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable {
static final long serialVersionUID = -5024744406713321676L;
//卖个关子,这里为啥要用transient关键字? 评论区见哦!
private transient HashMap<E,Object> map;
private static final Object PRESENT = new Object();
public HashSet() {
map = new HashMap<>();
}
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
...
}
不用多说,是不没想到,原来HashSet是基于HashMap实现的,元素都存到HashMap键值对的Key上面,而Value时有一个统一的值private static final Object PRESENT = new Object();
底层实现,源码如下:
public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, java.io.Serializable {
private transient NavigableMap<E,Object> m;
private static final Object PRESENT = new Object();
TreeSet(NavigableMap<E,Object> m) {
this.m = m;
}
public TreeSet() {
this(new TreeMap<E,Object>());
}
public boolean add(E e) {
return m.put(e, PRESENT)==null;
}
}
我去,又是这个尿性,基于TreeMap来实现的底层实现,源码如下:
public class LinkedHashSet<E> extends HashSet<E> implements Set<E>, Cloneable, java.io.Serializable {
private static final long serialVersionUID = -2851667679971038690L;
public LinkedHashSet(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor, true);
}
public LinkedHashSet(int initialCapacity) {
super(initialCapacity, .75f, true);
}
public LinkedHashSet() {
super(16, .75f, true);
}
public LinkedHashSet(Collection<? extends E> c) {
super(Math.max(2*c.size(), 11), .75f, true);
addAll(c);
}
}
都是super,实现了把HashSet中预留的构造方法启用了,因而可以实现有序插入(LinkedHashMap再谈究竟)Jdk1.7数据存储结构(采用数组+链表)
Jdk1.8数据存储结构(采用数组+链表+红黑树)
注意:在链表长度大于8后,查询复杂度由O(n)变为O(logn),将链表存储转换成红黑树存储(也就是TreeMap)
红黑树R-B Tree简介(本质其实是2-3-4树):
二叉树特性:
(1)左字数上所有的节点的值都小于或等于他的根节点上的值
(2)右子树上所有节点的值均大于或等于他的根节点的值
(3)左、右子树也分别为二叉树
红黑树特点(一种平衡二叉树):
(1)每个结点要么是红的要么是黑的。
(2)根结点是黑的。
(3)每个叶结点(叶结点即指树尾端NIL指针或NULL结点)都是黑的。
(4)如果一个结点是红的,那么它的两个儿子都是黑的。
(5)对于任意结点而言,其到叶结点树尾端NIL指针的每条路径都包含相同数目的黑结点
节点操作:
(1)左旋
(2)右旋
(3)变色
底层实现,源码如下:
static class Entry<K,V> extends HashMap.Node<K,V> {
//这里维护了一个before和after的Entry, 见名思意, 就是每个Entry<K,V>都维护它的上一个元素和下一个元素的关系。这也是LinkedHashMap有序的关键所在。
Entry<K,V> before, after;
Entry(int hash, K key, V value, Node<K,V> next) {
super(hash, key, value, next);
}
}
LinkedHashMap是继承HashMap, 也就是说LinkedHashMap的结构也是和HashMap那样(数组+链表)
注意:LinkedHashMap分为插入的顺序排列和访问的顺序排列两种方式,通过accessOrder参数来控制
个人博客地址:
csdn:https://blog.csdn.net/tiantuo6513
cnblogs:https://www.cnblogs.com/baixianlong
segmentfault:https://segmentfault.com/u/baixianlong
github:https://github.com/xianlongbai
原文:https://www.cnblogs.com/baixianlong/p/10703558.html