配列リスト
- 注文したコレクション
- 非スレッドセーフ
- 内部的に維持されているアレイによるデータストレージ
- 挿入が遅い(配列の拡張の問題が含まれます。配列のデフォルトの長さは10です。デフォルトの長さを超えると、L(現在の長さ)+ L / 2のたびに拡張が実行されます。
ただし、コレクションの長さがわかっている場合は、初期化中に配列の長さを指定することで拡張を回避できます。 ArrayList(100);
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);
}
- インデックス操作に従って配列を直接読み取ります(同じトラバーサルが高速です)。
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
LinkedList
- 注文したコレクション
- 非スレッドセーフ
- 二重リンクリストの内部メンテナンスによるデータストレージ
- 比較的高速に挿入(リンクリストの最後にノードを直接挿入)
- 読み取りが比較的遅い(1-L / 2リンクリストを走査する必要がある)
Node<E> node(int index) {
// assert isElementIndex(index);
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
まとめ
ArrayListの使用シナリオ:
クエリの頻度が挿入の頻度よりも大きい||コンテナの長さが予測できる
LinkedListの使用のシナリオ:
挿入の頻度がクエリの頻度よりも大きい&&コンテナの長さが予測できない