少し前までは、開発作業が比較的簡単だったので、いくつかのコレクションクラスをカプセル化する方法を学びました。今日は、LinkListとArrayListの類似点と相違点を要約します。
同じ点 |
ArrayListとLinkedListはどちらもインターフェイスListの実装クラスであることがわかります。つまり、size()、isEmpty()、contains()、add()、remove(など、両方に同じメソッドが必要です。 )、get()、set()などですが、それらの実装はまったく異なります
差 |
1つは、基礎となるデータ構造です。
ArrayListは:動的配列構造に
基づくLinkedList:リンクリストのデータ構造に基づく
2.各パフォーマンスの比較
データ構造の違いにより、2つのパフォーマンスには長所と短所があります。ランダムアクセス、ArrayListの方が効率的です。一般的なタスクでは、LinkedListは追加および削除操作のパフォーマンスが優れていますが、実際、ソースコードを見ると、2つが高速で、低速が単純に判断されていないことがわかります。 get、remove、addの2つのメソッドのソースコードを見てみましょう。
配列リスト:
//set
public E set(int index, E e) {
rangeCheck(index);
checkForComodification();
E oldValue = ArrayList.this.elementData(offset + index);
ArrayList.this.elementData[offset + index] = e;
return oldValue;
}
//get
public E get(int index) {
rangeCheck(index);
checkForComodification();
return ArrayList.this.elementData(offset + index);
}
//add
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
//remove
public E remove(int index) {
rangeCheck(index);
modCount++;
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;
}
LinkedList:
//add
public void add(int index, E element) {
checkPositionIndex(index);
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
//set
public E set(int index, E element) {
checkElementIndex(index);
Node<E> x = node(index);
E oldVal = x.item;
x.item = element;
return oldVal;
}
//get
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
//remove
public E remove(int index) {
checkElementIndex(index);
return unlink(node(index));
}
//节点定位
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;
}
}
配列が削除または追加されると、System.arraycopy()メソッドが使用されます。このメソッドは、配列内のオブジェクトの移動プロセスを記述し、node()メソッドはリンクリストを追加または削除するために使用されます。この方法はノードの配置であるため、一般に、2つの速度はあまり確実ではありません。