线性表
1. 定义
最简单的一种数据结构。形如A1、A2、A3….An这样含有有限的数据序列
2. 常用的两种形式:
- 顺序表示(其实就是数组)
- 链表表示
3. 顺序实现---ArrayList
- 初始化---默认初始化容量为0,首次调用add方法,容量初始化为10
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
- 1.5倍扩容
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
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);
}
- 在迭代器中会检测是否有修改,迭代过程中不允许修改
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
- 最大分配长度可能小于Integer.Max,跟堆大小有关。
- 连续分配内存空间。可能浪费大量内存空间。
4. 链表实现---LinkedList
- 初始化---默认初始化不做任何事,在add的时候,将add的node作为头尾节点
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
- 使用双向链表实现
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;
}
}
- 非连续分配内存空间,使用指针