List子接口:存储有序的、可重复的数据----->“动态”数组,注意:此处不是真正的动态数组
**ArrayList:作为List的主要实现类;主要特点有线程不安全,但是执行效率高效,底层实现是数组结构(Collections中定义了synchronizedList(List list)将此ArrayList转化为线程安全的)
**LinkedList:对于频繁的插入、删除操作,我们建议使用此类,因为它的执行效率高;但是内存消耗比ArrayList大;底层实现的双向链表实现
**Vector:List的古老实现类;线程安全的,效率低;底层使用数组实现的(如今逐渐被淘汰)
ArrayList源码分析:
jdk7:
ArrayList list = new ArrayList();//初始化一个长度为10的Object[] elementData
System.our.println(list.size());//返回存储的元素的个数:0
list.add(123);
list.add(456);
...
当添加第11个元素时,需要扩容,默认扩容为原来的1.5倍。还需要将原有数组中的数据复制到新的数组中。
删除操作:如果删除某一个数组位置的元素,需要其后面的元素依次前移。
remove(Object obj)/remove(int index)
jdk8:
ArrayList list = new ArrayList();//初始化一个长度为0的Object[] elementData
System.our.println(list.size());//返回存储的元素的个数:0
list.add(123);//此时才创建一个长度为10的Object[] elementData
list.add(456);
...
当添加第11个元素时,需要扩容,默认扩容为原来的1.5倍。还需要将原有数组中的数据复制到新的数组中。
实际开发中的启示:
1.建议使用:ArrayList list = new ArrayList(int length);
2.jdk8延迟了底层数组的创建:内存的使用率;对象的创建更快(jdk7为饿汉式,jdk8为懒汉式)
LinkedList源码分析:
LinkedList:底层使用双向链表存添加的元素
void linkLast(E e){
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = new Node;
if(l == null){
first = new Node;
}else{
l.next = new Node;
}
size++;
modCount++;
}
内部类体现:
private static class Node<E>{
E item;
Node<E> next;
Node<E> prev;
}
拓展1:LinkedHashMap源码分析
LinkedHashMap继承于HashMap,在HashMap底层结构的基础上额外添加一对链表:
static class Entry<K, V> extends HashMap.Node<K, V>{
Entry<K, V> before, after;
}