目录
List自身提供了和index相关的方法
List的特点
List的常见实现类
ArrayList
底层数据结构是数组
懒加载的体现
最大容量为int类型的最大值
扩容机制
使用equals方法来判断是否包含某个元素
随机增删元素效率较低,需要移动元素,时间复杂度为O(n)
LinkedList
底层数据结构是双向链表
add(E e)和remove()方法
获取元素需要遍历节点,效率较低,时间复杂度为O(n)
随机增删元素效率高,只需要改变指针指向即可,时间复杂度为O(1)
可以用作栈
可以用作队列
本身就是双向队列
package java.util;
public interface List extends Collection {
// ...
boolean addAll(int index, Collection extends E> c);
E get(int index);
E set(int index, E element);
void add(int index, E element);
E remove(int index);
// ...
}
//使用数组存放元素
transient Object[] elementData;
// 默认初始化容量
private static final int DEFAULT_CAPACITY = 10;
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
transient Object[] elementData;
// 使用无参构造器创建对象,并没有为数组开辟空间,仅仅指定为空数组
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
// 添加元素
public boolean add(E e) {
ensureCapacityInternal(size + 1);
//...
}
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
// 创建集合时,使用的是无参构造器
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
// 第一次添加元素
// 返回值是DEFAULT_CAPACITY,也就是10
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
// ...
}
// minCapacity是10
private void ensureExplicitCapacity(int minCapacity) {
// ...
if (minCapacity - elementData.length > 0)
// 走扩容的逻辑
grow(minCapacity);
}
// minCapacity是10
private void grow(int minCapacity) {
// ...
// newCapacity = 10
newCapacity = minCapacity;
// 创建长度为10的数组
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private void grow(int minCapacity) {
// ...
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
// ...
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// 拿到的newCapacity的值可以是int的最大值
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
// 这里返回了int的最大值
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
private void grow(int minCapacity) {
// 旧数组容量
int oldCapacity = elementData.length;
// 新容量为旧容量的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 新容量达不到最低容量要求
if (newCapacity - minCapacity < 0)
// 新容量赋值为最低要求的容量
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// 新数组
elementData = Arrays.copyOf(elementData, newCapacity);
}
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
// 使用的是equals方法
if (o.equals(elementData[i]))
return i;
}
return -1;
}
// 随机增加元素
public void add(int index, E element) {
// ...
// 元素移动
System.arraycopy(elementData, index, elementData, index + 1, size - index);
elementData[index] = element;
size++;
}
// 随机删除元素
public E remove (int index){
// ...
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
// 元素移动
System.arraycopy(elementData, index + 1, elementData, index, numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
// 节点
private static class Node {
// 节点数据值
E item;
// next指针,指向下一个节点
Node next;
// prev指针,指向上一个节点
Node prev;
Node(Node prev, E element, Node next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
// 添加元素
public boolean add(E e) {
// 从尾部添加
linkLast(e);
return true;
}
void linkLast(E e) {
final LinkedList.Node l = last;
final LinkedList.Node newNode = new LinkedList.Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
// 删除元素
public E remove() {
// 从头部删除元素
return removeFirst();
}
public E removeFirst() {
final LinkedList.Node f = first;
if (f == null)
throw new NoSuchElementException();
return unlinkFirst(f);
}
private E unlinkFirst(Node f) {
final E element = f.item;
final LinkedList.Node next = f.next;
f.item = null;
f.next = null; // help GC
first = next;
if (next == null)
last = null;
else
next.prev = null;
size--;
modCount++;
return element;
}
// 根据下标获取元素
public E get(int index) {
//...
return node(index).item;
}
Node node(int index) {
if (index < (size >> 1)) {
Node x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
// 随机添加元素
public void add(int index, E element) {
// ...
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
void linkLast(E e) {
final Node l = last;
final Node newNode = new Node<>(l, e, null);
// 改变指针指向
last = newNode;
if (l == null)
// 改变指针指向
first = newNode;
else
// 改变指针指向
l.next = newNode;
size++;
modCount++;
}
void linkBefore(E e, Node succ) {
final Node pred = succ.prev;
final Node newNode = new Node<>(pred, e, succ);
// 改变指针指向
succ.prev = newNode;
if (pred == null)
// 改变指针指向
first = newNode;
else
// 改变指针指向
pred.next = newNode;
size++;
modCount++;
}
// 入栈,从链表的头部添加元素
public void push(E e) {
addFirst(e);
}
// 出栈,从链表的头部删除元素
public E pop() {
return removeFirst();
}
// 入队,从链表的尾部添加元素
public boolean offer(E e) {
return add(e);
}
// 出队,从链表的头部删除元素
public E poll() {
final Node f = first;
return (f == null) ? null : unlinkFirst(f);
}
// 实现了Deque接口,两端都可以添加和删除元素
public class LinkedList
extends AbstractSequentialList
implements List, Deque, Cloneable, java.io.Serializable
// 头部添加元素
public boolean offerFirst(E e) {
addFirst(e);
return true;
}
// 尾部添加元素
public boolean offerLast(E e) {
addLast(e);
return true;
}
// 头部删除元素
public E pollFirst() {
final LinkedList.Node f = first;
return (f == null) ? null : unlinkFirst(f);
}
// 尾部删除元素
public E pollLast() {
final LinkedList.Node l = last;
return (l == null) ? null : unlinkLast(l);
}