Java 常用容器笔记
ArrayList
基本特点:基于数组,便于按 index 访问,超过数组需要扩容,扩容成本较高。
用途:大部分情况下操作一组数据都可以用 ArrayList 原理:使用数组模拟列表,默认大小 10,扩容 x1.5,newCapacity = oldCapacity + (oldCapacity >> 1)。
安全问题:
1、写冲突:
- 两个写,相互操作冲突
2、读写冲突:
- 读,特别是 iterator 的时候,数据个数变了,拿到了非预期数据或者报错
- 产生 ConcurrentModificationException
LinkedList
基本特点:使用链表实现,无需扩容。
用途:不知道容量,插入变动多的情况。
原理:使用双向指针将所有节点连起来。
安全问题:
1、写冲突:
- 两个写,相互操作冲突
2、读写冲突:
- 读,特别是 iterator 的时候,数据个数变了,拿到了非预期数据或者报错
- 产生 ConcurrentModificationException
List 线程安全的简单办法
既然线程安全是写冲突和读写冲突导致的最简单办法就是,读写都加锁。
CopyOnWriteArrayList
核心改进原理:
1、写加锁,保证不会写混乱。
2、写在一个 Copy 副本上,而不是原始数据上(GC young 区用复制,old 区用本区内的移动)。
HashMap
基本特点:空间换时间,哈希冲突不大的情况下查找数据性能很高。
用途:存放指定 key 的对象,缓存对象。
原理:使用 hash 原理,存 k-v 数据,初始容量 16,扩容 x2,负载因子 0.75。
JDK8 以后,在链表长度到 8 & 数组长度到 64 时,使用红黑树。
安全问题:
1、写冲突
2、读写问题,可能会死循环
3、keys()无序问题
版权声明: 本文为 InfoQ 作者【风翱】的原创文章。
原文链接:【http://xie.infoq.cn/article/a986ccaf256774133768e5e10】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论