工作生活

java集合框架总结

2019-07-01  本文已影响0人  清雨季

一 java 集合框架图

image.png

二 List

2.1 ArrayList

底层数据结构:线性表(数组)
线程安全:否
核心字段:

字段名 类型 作用 备注
elementData Object[] 保存数据 -
size int 长度 -
modCount int 被修改的次数 -

初始化过程:
若带有容量参数,则使用此容量来初始化elementData,否则把elementData置为空数组

扩容方式:

modCount的作用:
使用迭代器循遍历ArrayList时,用于检测是否在迭代过程中被修改,即检测ConcurrentModificationException。

2.2 LinkedList

底层数据结构:双向链表

    private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;
    }

线程安全:否
核心字段:

字段名 类型 作用 备注
size int 长度 -
first Node 头节点 -
last Node 尾节点 -

2.3 Vector

ArrayList的线程安全版本
底层数据结构:线性表
线程安全:是

初始化:
默认初始化容量为10,也可以指定大小。

扩容:
初始化时可指定每次扩容增加的容量数,如果没有指定,则每次都翻倍

线程安全方式:
为每个方法都加上synchronized关键字

三 Map

3.1 HashMap

底层数据结构:桶链结构,跳表
是否线程安全:否

核心字段:

字段名 类型 作用 备注
table Node[] 底层数据,即桶链 -
entrySet Set<Map.Entry<K,V>> 所有的节点数据 与table重复,主要是为了entrySet()和values()方法
size int 数据量 -
threshold int 扩容阀值 -
loadFactor float 扩容因子 -

hash函数:

return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);

为什么要这么设计?因为使用hash值散列到桶时,使用的是取余数的方法,这导致hash碰撞的机率只与hashCode的后几位有关,这个函数相当于把高位的值"混"在了低位中。可以参考HashMap的hash函数为什么这么设计

怎么使用hashCode映射到数组的下标的?

首先使用上面的方式,设计出hash值

hash = (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16)

然后作以下计算

index = (n - 1) & hash

n为数组长度,在HashMap中,n的值一定为2的整数次幂,所以n-1的两进制码一定是000...001111..111结构的。因此这个操作实际上是取了hash值的后面几位

扩容机制:

红黑树:

3.2 TreeMap

排序Map,底层采用红黑树实现,线程不安全
核心字段:

字段名 类型 作用 备注
comparator Comparator 比较器,用于排序 -
root Entry 根节点 -
size int 数据长度 -
modCount int 修改次数 -

实现了NavigableMap,可以获取指定Key范围的数据

3.3 其他Map

四 Set

4.1 HashSet

底层使用HashMap实现,使用HashMap的Key来保存元素,所有的事都交给了HashMap处理,HashSet自己并没有什么额外的逻辑,可以说就是单纯的一层包装。
有三个构造方法,不同的构造方法会使用不同的HashMap:

    public HashSet(int initialCapacity, float loadFactor) {
        map = new HashMap<>(initialCapacity, loadFactor);
    }
    public HashSet(int initialCapacity) {
        map = new HashMap<>(initialCapacity);
    }
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }

可以看出如果带有dummy参数,则会使用LinkedHashMap

4.2 TreeSet

同上,只是TreeSet的一层简单包装,没有特殊逻辑。

4.3 IdentitySet

同上,包装了IdentityHashMap

4.4 LinkedHashSet

继承自HashSet,初始化时调用了父类的带有dummy参数的构造方法,在此它实际上也是LinkedHashMap的一层包装。

参考文档

modCount的作用
HashMap的hash函数为什么这么设计
30张图带你彻底理解红黑树

上一篇 下一篇

猜你喜欢

热点阅读