集合类或者接口系列之List
1. 基本信息
-
是一个接口、继承自Collection接口(Collection接口继承自Iterable接口)
-
子类:Vector、ArrayList、linkedlist、(Stack是Vector的子类)
-
有序集合、允许重复元素、允许null
-
关系图:
2. 常见子类详解
2.1 vector:
-
底层是数组,线程安全,增删、查询都慢(基本不再使用,已经被
ArrayList
替代) -
默认构造的内部数组初始化大小为10
public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { //... public Vector() { this(10); } public Vector(int initialCapacity) { this(initialCapacity, 0); } //... }
-
扩容机制:默认是之前的两倍
2.2 ArrayList:
-
底层是数组,大小可变,线程不安全,查询速度快,增删速度慢。是vector的替代方案,如果需要使用多线程,可以对ArrayList加锁,用Collections类中的静态方法
SynchronizedList()
-
ArrayList()构造函数默认初始化一个容量为10的空列表
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{ //... private static final int DEFAULT_CAPACITY = 10;//初始化容器长度,不够再扩容 private static final Object[] EMPTY_ELEMENTDATA = {};//空数组 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//确定容量 transient Object[] elementData; //元素数组 public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } //... }
注意:RandomAccess表示支持随机访问,即根据下标访问
-
扩容机制:默认是1.5倍
private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1);//扩容1.5 if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); }
在每次向容器中增加元素的同时都会进行容量检查
如果我们明确所插入元素的多少,最好指定一个初始容量值,避免过多的进行扩容操作而浪费时间、效率。
2.3 linkedlist:
-
(双向)链表数据结构,线程不安全,插入、删除速度快,查询速度慢。
-
构造空链表
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable { //... transient int size = 0;//链表长度 transient Node<E> first;//首节点 transient Node<E> last;//尾节点 //每个节点都包含下一个节点的地址信息 public LinkedList() { } //... }
2.4 Stack:
- 继承自vector,先进后出的堆栈
- 方法:push、pop、peek(栈顶)、empty、search
3. 总结
3.1 重点
- 数据结构、应用场景、线程安全
3.2 常见面试题
-
ArrayList和LinkedList分别使用场景?
ArrayList:查询较多的场景
LinkedList:插入较多的情景
-
如何复制某个ArrayList到另一个ArrayList中去?
- clone()方法
ArrayList oldArrayList = new ArrayList(); ArrayList newArrayList = (ArrayList) oldArrayList.clone();
- 构造方法
ArrayList oldArrayList = new ArrayList(); ArrayList newArrayList = new ArrayList(oldArrayList);
- 使用Collection的copy方法
-
List和Array之间如何互相转换?
ArrayList ArrayList = new ArrayList(); Object[] array = ArrayList.toArray();//list--->array List<Object> list = Arrays.asList(array);//array--->list