ArrayList底层实现是基于数组的,所以对指定下标的查找和修改比较快,可是删除和插入操做比较慢。算法
构造ArrayList时尽可能指定容量,减小扩容时带来的数组复制操做,若是不知道大小能够赋值为默认容量10。数组
每次添加元素以前会检查是否须要扩容,每次扩容都是增长原有容量的一半。(扩容是建立一个新的数组,并将原来的数组元素迁移到新数组中)安全
每次对下标的操做都会进行安全性检查,若是出现数组越界就当即抛出异常。数据结构
ArrayList的全部方法都没有进行同步,所以它不是线程安全的。多线程
以上分析基于JDK1.7,其余版本会有些出入,所以不能一律而论函数
private static class Node<E> { E item; //元素 Node<E> next; //下一个节点 Node<E> prev; //上一个节点 Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } }
LinkedList是基于双向链表实现的,不管是增删改查方法仍是队列和栈的实现,均可经过操做结点实现性能
LinkedList无需提早指定容量,由于基于链表操做,集合的容量随着元素的加入自动增长(无需执行默认长度,也没有扩容需求)this
LinkedList删除元素后集合占用的内存自动缩小,无需像ArrayList同样调用trimToSize()方法spa
LinkedList的全部方法没有进行同步,所以它也不是线程安全的,应该避免在多线程环境下使用线程
LinkedList根据index查询时采起的是二分法,即index小于总长度一半时从链表头开始日后查找,大于总长度一半时从链表尾往前查找。若是是根据元素查找,则须要从头开始遍历
以上分析基于JDK1.7,其余版本会有些出入,所以不能一律而论。
static class Entry<K,V> implements Map.Entry<K,V> { final K key; //键 V value; //值 Entry<K,V> next; //下一个Entry的引用 int hash; //哈希码 ... //省略下面代码 }
//生成hash码的函数 final int hash(Object k) { int h = hashSeed; //key是String类型的就使用另外的哈希算法 if (0 != h && k instanceof String) { return sun.misc.Hashing.stringHash32((String) k); } h ^= k.hashCode(); //扰动函数 h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); }