ArrayList、LinkedList、LinkedHashMap源码分析
来源:互联网 发布:闪电网络测速工具 编辑:程序博客网 时间:2024/06/05 07:46
本文是看ArrayList、LinkedList、LinkedHashMap源码的一个小结
ArrayList
abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>
ArrayList是基于数组实现的,相对于数组,它支持自动扩容。
ArrayList非线程安全,因此也通过modCount来校验。
rivate class SimpleListIterator implements Iterator<E> { int pos = -1; int expectedModCount; int lastPosition = -1; SimpleListIterator() { expectedModCount = modCount; } public boolean hasNext() { return pos + 1 < size(); } public E next() { if (expectedModCount == modCount) { try { E result = get(pos + 1); lastPosition = ++pos; return result; } catch (IndexOutOfBoundsException e) { throw new NoSuchElementException(); } } throw new ConcurrentModificationException(); } public void remove() { if (this.lastPosition == -1) { throw new IllegalStateException(); } if (expectedModCount != modCount) { throw new ConcurrentModificationException(); } try { AbstractList.this.remove(lastPosition); } catch (IndexOutOfBoundsException e) { throw new ConcurrentModificationException(); } expectedModCount = modCount; if (pos == lastPosition) { pos--; } lastPosition = -1; } }
数据结构
/** * The number of elements in this list. */ int size; /** * The elements in this list, followed by nulls. */ transient Object[] array;数据结构相当简单,当前元素数量size,和一个数组。
自动扩容
ArrayList基本上和数组一样,看一下怎么自动扩容的:
if (s < a.length) { System.arraycopy(a, index, a, index + 1, s - index); } else { // assert s == a.length; Object[] newArray = new Object[newCapacity(s)]; System.arraycopy(a, 0, newArray, 0, index); System.arraycopy(a, index, newArray, index + 1, s - index); array = a = newArray; }容量不够时,创建了一个新的数组替代原来的array。
扩容逻辑如下:
private static int newCapacity(int currentCapacity) { int increment = (currentCapacity < (MIN_CAPACITY_INCREMENT / 2) ? MIN_CAPACITY_INCREMENT : currentCapacity >> 1); return currentCapacity + increment; }
private static final int MIN_CAPACITY_INCREMENT = 12;最小容量增量12, 当前容量小于6时,增量会最小增量;否则,增量为当前容量的一半,即容量增加二分之一。
LinkedList
LinkedList是双向队列, 实现了Deque接口。
class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Queue<E>, Cloneable, Serializable
public E get(int location) { if (location >= 0 && location < size) { Link<E> link = voidLink; if (location < (size / 2)) { for (int i = 0; i <= location; i++) { link = link.next; } } else { for (int i = size; i > location; i--) { link = link.previous; } } return link.data; } throw new IndexOutOfBoundsException(); }由于它实现了Deque接口,因此它也可以是个不严格的栈(控制只从一头进出)。
节点结构
private static final class Link<ET> { ET data; Link<ET> previous, next; Link(ET o, Link<ET> p, Link<ET> n) { data = o; previous = p; next = n; } }
支持null值
public boolean add(E object) { return addLastImpl(object); } private boolean addLastImpl(E object) { Link<E> oldLast = voidLink.previous; Link<E> newLink = new Link<E>(object, oldLast, voidLink); voidLink.previous = newLink; oldLast.next = newLink; size++; modCount++; return true; }add()方法并没有对null值做特殊处理,比如不支持null值的Hashtable会抛出异常。
因此LinkedList支持null值。
LinkedHashMap
LinkedHashMap继承了HashMap,在HashMap的基础上把HashMap的Entry串成了双向队列。
其节点在HashMap的Entry的基础上加上了前、后指针
static class LinkedEntry<K, V> extends HashMapEntry<K, V> { LinkedEntry<K, V> nxt; LinkedEntry<K, V> prv; /** Create the header entry */ LinkedEntry() { super(null, null, 0, null); nxt = prv = this; } /** Create a normal entry */ LinkedEntry(K key, V value, int hash, HashMapEntry<K, V> next, LinkedEntry<K, V> nxt, LinkedEntry<K, V> prv) { super(key, value, hash, next); this.nxt = nxt; this.prv = prv; } }简单的说,LinkedHashMap就是HashMap和LinkedList的合体。
accessOrder和LRU算法
private final boolean accessOrder;
accessOrder,字面意思访问顺序
if (accessOrder) makeTail((LinkedEntry<K, V>) e);
private void makeTail(LinkedEntry<K, V> e) { // Unlink e e.prv.nxt = e.nxt; e.nxt.prv = e.prv; // Relink e as tail LinkedEntry<K, V> header = this.header; LinkedEntry<K, V> oldTail = header.prv; e.nxt = header; e.prv = oldTail; oldTail.nxt = header.prv = e; modCount++; }
当accessOrder为false的时候,什么都不做,和原先的一模一样
为ture时,调用makeTail()把当前访问的节点挪到了链表的最后面。
以下代码的输出值为"[3=3, 4=4, 1=1, 2=2]"
Map<String, Integer> map = new LinkedHashMap<String, Integer>(16,0.75f,true); map.put("1", 1); map.put("2", 2); map.put("3", 3); map.put("4", 4); map.get("1"); map.get("2"); System.out.print(map.entrySet());
阅读全文
0 0
- ArrayList、LinkedList、LinkedHashMap源码分析
- ArrayList LinkedList 源码分析
- ArrayList,LinkedList源码分析
- ArrayList与LinkedList源码分析
- ArrayList和linkedList源码分析
- 源码分析ArrayList/Vector/LinkedList
- ArrayList LinkedList源码分析,性能分析
- ArrayList和LinkedList的源码分析
- 五、HashMap、ArrayList、LinkedList源码分析
- java 之 ArrayList 、LinkedList分析源码
- ArrayList和LinkedList add的源码分析
- ArrayList和LinkedList源码分析总结
- ArrayList LinkedList源码解析
- 常用集合ArrayList,LinkedList,HashMap,HashSet源码分析
- Java集合框架之List---ArrayList与LinkedList源码分析
- Java中arraylist和linkedlist源码分析与性能比较
- 常用集合ArrayList,LinkedList,HashMap,HashSet源码分析
- Java ArrayList与LinkedList源码分析与比较
- NGUI图集创建及图集内图片的删除、更新、添加
- 108. Convert Sorted Array to Binary Search Tree
- 聊天输入控件封装
- 技术文章收集
- maven入门教程
- ArrayList、LinkedList、LinkedHashMap源码分析
- HDU 1796 How many integers can you find【容斥原理】
- Centos5.5 IDT HOOK
- Python交互环境下如何输入代码
- php搭建环境
- Nginx反向代理以伪装站点登录
- OkHttp源码分析
- iOS/Swift3.0 终端命令自动打包
- Maven实践---导航