table of Contents
The amount of, first of all, because basically left and right copy copy copy copy, I basically forgot where to copy over, just for the convenience of their own review, if you see your content, please reply link, I will state reprint.
1 Overview
Collection Interface
- Set Interface: disorder, can not be repeated
- List Interface: orderly, repeatable
Map Interface
- Key-value pairs
- Not inherit Collection
- Unique
Map collections | key is null | Value is null |
---|---|---|
HashMap | √ | √ |
TreeMap | × | √ |
ConcurrentMap | × | × |
2 List Interface
Orderly, repeatable
Location Access Method
void add(int index, E e) // 将元素e插入到index处
boolean addAll(int index, Collection<? extends E> c)// 将集合c中所有元素插入到List集合的index处
E get(int index) // 返回index处的元素
E remove(int index) // 移除index处的元素
E set(int index, E e) // 将index处元素替换成e,并返回替换后的元素
Seek
int indexOf(Object o) // 返回对象o再List中出现的位置
int lastIndexOf(Object o) // 返回对象o在List中最后一次出现的位置
View range
List subList(int fromIndex, int toIndex)//返回从fromIndex(包括)到toIndex(不包括)处所有元素集合组成的子集合
List iterator
ListIterator<E> listIterator() // 返回List的ListIterator,初始位置索引为0
ListIterator<E> listIterator(int index) // 返回List的ListIterator,初始位置索引为index
The new method ListIterator
public interface ListIterator<E> extends Iterator<E> {
void add(E e); // 在游标 前面 插入一个元素(注意,是前面)
boolean hasPrevious(); // 判断游标前面是否有元素
int nextIndex(); // 返回游标后边元素的索引位置,初始为 0
E previous(); // 返回游标前面的元素,同时游标前移一位。游标前没有元素就报 java.util.NoSuchElementException 的错
int previousIndex(); // 返回游标前面元素的位置,初始时为 -1,同时报 java.util.NoSuchElementException 错;
void set(E e); // r更新迭代器最后一次操作的元素为 E,也就是更新最后一次调用 next() 或者 previous() 返回的元素。当没有迭代,也就是没有调用 next() 或者 previous() 直接调用 set 时会报 java.lang.IllegalStateException 错
}
Iterator
public class Demo {
public static void main(String[] args) {
ArrayList<String> arr = new ArrayList<>();
arr.add("a");
arr.add("b");
arr.add("c");
arr.add("d");
Iterator<String> iterator = arr.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
List realization
2.1 ArrayList
List an interface implementation class, the bottom is an array
- get, set fast
- remove, insert slow
- add fast
The initial space: 10 by default. When copying the other array, the array is 110% open space
Space expansion: the original array size of the original array size >> 1 +
2.2 LinkedList
The bottom layer is a two-way circular list
- Beyond the end where you add, delete fast
- Find a large number of random access, slow
2.3 CopyOnWriteArrayList
When writing copy for reading and writing less
Separate read and write
A write operation on a copy of the array, the read operation or in the original array, separate read and write, independently of each other.
Write operation requires locking to prevent data loss resulting in write concurrent writes.
You need to copy the original array to the new array after the end of the write operation.
2.4 Complexity
get: index is known, to obtain the position of the element index
contains: index unknown, to find an element
3 Set Interface
Disorder, can not be repeated
6 implementation class, two interfaces
3.1 HashSet
- Objects can not be repeated
- HashMap implemented with the underlying object is a bond, the value of the flag
- Traversal using the HashMap
map.keySet().iterator()
- 并发:不同步、线程不安全
3.2 LinkedHashSet
- 底层使用LinkedHashMap实现
- 链表使用双向链表实现(有序)
- 用于有序消除重复元素(重写hashcode与equal)
- 并发:不同步、线程不安全、迭代器快速失效
3.3 CopyOnWriteArraySet
- 底层使用CopyOnWriteArrayList实现
- 不适用于大量查找和插入操作
- 适用于:白名单,黑名单,商品类目的访问和更新场景
- 并发:线程安全、读写分离迭代器
3.4 EnumSet
初始化
enumset为抽象类,不可直接new
底层使用RegularEnumSet(long-64),或者JumboEnumSet(long数组)如果枚举值个数小于等于64,则静态工厂方法中创建的就是RegularEnumSet,大于64的话就是JumboEnumSet。
静态构造函数
<E extends Enum<E>> EnumSet<E> of(E first, E... rest)
// 创建包含指定元素的集合
<E extends Enum<E>> EnumSet<E> range(E from, E to)
//初始集合包括枚举值中指定范围的元素
<E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType)
// 创建一个初始包含elementType中的所有元素的集合
<E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType)
// 创建一组元素类型,初始值为空
适用于求 交集、并集、补集
3.5 TreeSet
- 底层算法使用 红黑树
- 使用TreeMap类实现
- 有序
并发:不同步、线程不安全、迭代器快速失效
补充:二叉树
只有两棵子树,度≤2
二叉树的性质
- 若二叉树的层次从0开始,则在二叉树的第i层至多有 2^i^个结点(i>=0)
- 高度为k的二叉树最多有2^k^ - 1个结点(k>=-1)(空树的高度为-1)
- 对任何一棵二叉树,如果其叶子结点数为m, 度为2的结点数为n, 则m = n + 1
二叉树的类型
二叉树的类型
遍历
- 前序遍历:根左右
- 中序遍历:左根右
- 后序遍历:左右根
前序遍历:A B C D E F G H K
中序遍历:B D C A E H G K F
后序遍历:D C B H K G F E A
分析如下
3.6 ConcurrentSkipListSet
插入图解:
查找图解
- 底层ConcurrentSkipListMap实现
- 随机因子(用于随机选择level1的个数,线程安全的)
- 确定层数:level设置默认为1,然后对rnd进行一个右位移操作后在与1进行与操作后来确定需要分为几层
- cas保证线程安全
3.7 复杂度
4 Map 接口
键值对,不继承Collection,键唯一
Map方法
Map实现
4.1 HashMap
容量默认16
HashMap的bucket 数组大小一定是2的幂,若不是,寻找最近的的2的幂
结构如下
put方法流程
- 如果定位到的数组位置没有元素 就直接插入。
- 如果定位到的数组位置有元素就和要插入的key比较,如果key相同就直接覆盖,如果key不相同,就判断p是否是一个树节点,如果是就调用 e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value)将元素添加进入。如果不是就遍历链表插入(插入的是链表尾部)。
默认参数详解
为了减少hash值的碰撞,需要实现一个尽量均匀分布的hash函数,在HashMap中通过利用key的hashcode值,来进行位运算
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable {
// 序列号
private static final long serialVersionUID = 362498820763181265L;
// 默认的初始容量是16
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
// 最大容量
static final int MAXIMUM_CAPACITY = 1 << 30;
// 默认的填充因子
static final float DEFAULT_LOAD_FACTOR = 0.75f;
// 当桶(bucket)上的结点数大于这个值时会转成红黑树
static final int TREEIFY_THRESHOLD = 8;
// 当桶(bucket)上的结点数小于这个值时树转链表
static final int UNTREEIFY_THRESHOLD = 6;
// 桶中结构转化为红黑树对应的table的最小大小
static final int MIN_TREEIFY_CAPACITY = 64;
// 存储元素的数组,总是2的幂次倍
transient Node<k,v>[] table;
// 存放具体元素的集
transient Set<map.entry<k,v>> entrySet;
// 存放元素的个数,注意这个不等于数组的长度。
transient int size;
// 每次扩容和更改map结构的计数器
transient int modCount;
// 临界值 当实际大小(容量*填充因子)超过临界值时,会进行扩容
int threshold;
// 加载因子
final float loadFactor;
}
4.2 LinkedHashMap
构造
public LinkedHashMap(int initialCapacity,float loadFactor,boolean accessOrder)
Hashmap实体中添加before,after(双向链表)实现有序访问
LinkedHashMap添加head、tail(头指针和尾指针)
accessOrder
accessOrder: 为 false按插入顺序访问;为true,按访问顺序访问(LRU算法)
LRU实现
protected boolean removeEldestEntry(Map.Entry<K,V> eldest)
可以重载该方法自己定义策略
是否线程安全
不安全,迭代器快速失效
4.3 ConcurrentHashMap
实现原理
1.7
采用乐观读+分段锁实现 来 实现ConcurrentMap
ConcurrentHashMap 是由 Segment 数组结构和 HashEntry 数组结构组成
Segment 实现了 ReentrantLock
1.8
采用CAS和synchronized来保证并发安全。数据结构跟HashMap1.8的结构类似,数组+链表/红黑二叉树。synchronized只锁定当前链表或红黑二叉树的首节点,这样只要hash不冲突,就不会产生并发,效率又提升N倍
其他
默认容量16
在获取size()会导致全锁,开销大
构造函数提供并发级别控制
4.4 Complexity
Forehead, emphasizing once again, because basically left and right copy copy copy copy, I basically forgot where to copy over, just for the convenience of their own review, if you see your content, please reply link, I will plus go.