リストのArrayList

リスト

リストのJavaは(も配列としても知られる)順序付きコレクションである、それはインターフェースです。このユーザインタフェースは、正確各要素がリストに挿入され、要素がインデックス要素(リスト中の位置)によって取得することができる見つけるために制御することができます。

異なるセットは、リスト要素もヌルが複数存在することを可能にする、繰り返させます。公式には禁止が彼の繰り返しリストを実現提唱していないことが示唆されました。リストには、イテレータ、追加、削除、等しいとhashCodeメソッドのコレクションを継承しています。

配列リスト

リストには、可変容量を達成するためのインタフェースの配列をそして、ベクトル大体同じですが、同期していません。前記大きさ、のisEmpty、取得、セット 、イテレータと反復子の時間計算量はO(1)です。時間計算の数に関連する操作を追加、N-O(N)を添加しました。線形複雑のため、より速くLinkedListの以外の操作。

2.1定義:

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
    private static final long serialVersionUID = 8683452581122892189L;

    private static final int DEFAULT_CAPACITY = 10;  // 默认数组初始大小

    private static final Object[] EMPTY_ELEMENTDATA = {}; // 空数组

    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; // 与EMPTY_ELEMENTDATA区分开,是用来衡量添加了第一个元素后,数组扩容了多大

    transient Object[] elementData; // 存放数据的数组,当新增第一个元素时,容量就到DEFAULT_CAPACITY


    private int size; // ArrayList大小
  • リストを達成するために、AbstractListを継承。配列キュー、追加、削除、修正するために、関連する提供、トラバーサル機能です
  • ランダムアクセス機能を提供実装RandmoAccessインターフェース、。高速ランダムアクセス、要素の数によって、オブジェクトのことができますすばやくアクセス要素。
  • 即ち機能クローンを()被覆実装Cloneableインタフェースは、クローニングすることができます
  • そのArrayListのサポートのシリアル化を意味したjava.io.Serializableインタフェースを実装し、伝送のシーケンスを経ます

2.2初期化

ArrayListの、すなわち、3つの初期化方法を提供します。

  • public ArrayList(){}:容量はアレイのからelementData DEFAULT_CAPACITY(10)に初期化されるには、これは実際には追加操作で達成されます。
  • public ArrayList(int initialCapacity) {}:配列リスト構造指定された容量
  • public ArrayList(Collection<? extends E> c) {}:付Arrays.copyOf()リストの指定された型の配列からなります

2.3増加

public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}

前記現在のアレイが充填され、特にensureCapacityInternalに新しい配列、(に元の配列をコピーするために再利用Arrays.copyOf()、拡張のための元のArrayListの容量の容量+ / 2に従って実装される)実装展開の鍵方式)は、(成長です。

private static int calculateCapacity(Object[] elementData, int minCapacity) { 
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { // 只有在第一次添加新元素时才会使用
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    return minCapacity;
}

private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}

private void ensureExplicitCapacity(int minCapacity) {
    modCount++;

    // overflow-conscious code
    if (minCapacity - elementData.length > 0) // 当前的数组已经满了,需要扩容
        grow(minCapacity);
}
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 > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE:MAX_ARRAY_SIZE来选
    // minCapacity is usually close to size, so this is a win:
    elementData = Arrays.copyOf(elementData, newCapacity);
}

2.4読書

ArrayListのは、達成するための配列なので、そこそこだけにインデックスをクリックして、非常に単純な読み、以下の対象に応じてランダムアクセスをサポートしています。

public E get(int index) {
    rangeCheck(index); // 越界判断

    return elementData(index);
}

2.5削除

ArrayListのは、実際に、プレスが配列で削除済みとしてマークされ、その後、ラベルの前方の背面に起因することができ、要素を削除する2つの方法を提供します

  • 押して[削除]マーク
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;
}
  • 要素の値は削除することによって第一次が等しくなる削除
public boolean remove(Object o) {
    if (o == null) {
        for (int index = 0; index < size; index++)
            if (elementData[index] == null) {
                fastRemove(index);  // 同上,只是不做越界判断,不返回值
                return true;
            }
    } else {
        for (int index = 0; index < size; index++)
            if (o.equals(elementData[index])) {
                fastRemove(index);
                return true;
            }
    }
    return false;
}

フェイルファストメカニズム

Javaエラー検出機構の集まりであるフェイルファストで高速失敗」、。複数のスレッドが構造変化のコレクションを操作するために、フェイルファスト機構を持っていることがあります。それが可能であることを忘れないでください、必ずしも例えば2つのスレッド(スレッド1とスレッド2)があると仮定し、イテレータによって糸横断要素は、ある時点でスレッド2が(上記の構造が変更されたセットの構造を変更し、設定します単純)要素のコレクションの内容を変更するのではなく、この時間ので、プログラムは失敗し、高速なメカニズムで、その結果、例外ConcurrentModificationExceptionをスローします。

フェイルファストのArrayList機構はmodCountによって保証され、その定義AbstractList、追加、削除、およびこの意志を実行modCountの値の変化の全体的な量は、ConcurrentModificationExceptionがスローされた例外に異なるexpectedModCountになります。

ソリューション:

  • 直接Collections.synchronizedList:同期ロック引き起こすため、欠失のため、お勧めできませんトラバーサル操作をブロックすることができます
  • 使用CopyOnWriteArrayListとは:データコピーの両方で最初のコピーは、操作を実行すると、削除データを追加しますが、スペース損失の多くを生成します。

おすすめ

転載: www.cnblogs.com/wongdongd/p/12339766.html