ArrayList、LinkedListは、ベクター、CopyOnWriteArrayListとの差とソースコード解析

1. ArrayListに

ArrayListのキューはに対応する配列であるダイナミックアレイ配列内のJavaと比較して、その容量を動的に成長することができますそれはAbstractList、実装リスト、ランダム・、Cloneableを、java.io.Serializableのこれらのインタフェースを継承します。デフォルトサイズは10である(ソースから分かるように1.5倍の各拡張能力、INT newCapacity = oldCapacity +(oldCapacity >> 1))。ArrayListの中の操作はスレッドセーフではありません!だから、唯一のシングルスレッドでのArrayListを使用することが推奨され、そして中に複数のスレッドのベクトルまたはCopyOnWriteArrayListとを選択することができます

パブリック クラスのArrayList <E>は拡張 AbstractList <E>
         道具一覧<E> ランダム・、Cloneableを、java.io.Serializableの
{ 
    ... 
    
    / ** 
     *デフォルトの初期容量を。
     * / 
    プライベート 静的 最終 int型の DEFAULT_CAPACITY = 10 ; 

    公共のArrayList(int型InitialCapacityの値){
         場合(InitialCapacityの値> 0 ){
             この .elementData = 新しいオブジェクト[InitialCapacityの値]。
        } それ以外の 場合(InitialCapacityの値== 0){
             この .elementDataは= EMPTY_ELEMENTDATAと、
        } {
             スロー 新しい例外:IllegalArgumentException( "不正な容量:" + 
                                               InitialCapacityの値を)。
        } 
    }     
    
    公共のArrayList(){
         この .elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA。
    } 
    
    公共のArrayList(コレクション<?拡張 E> C){ 
        ... 
    } 

    プライベート のボイドが成長(int型minCapacityに){
             //オーバーフロー意識コード
            INT oldCapacity = elementData.length。
            INT newCapacity = oldCapacity +(oldCapacity >> 1 )。
            もし(newCapacity - minCapacityに<0 
                    newCapacity = minCapacityに。
            もし(newCapacity - MAX_ARRAY_SIZE> 0 
                    newCapacity = hugeCapacity(minCapacityに)。
            // minCapacityには通常に近い大きさにあるので、これは勝利です: 
            からelementData = Arrays.copyOf(からelementData、newCapacity)。
        } 

    公共 int型のサイズ(){
        戻り値のサイズ; 
    } 

       ... 
}

1.1 ArrayListの展開

ArrayListのデフォルト容量が膨張が、各拡張コードすることができるから、1.5倍に増加したときに、最初の要素に11意志を挿入したとき、10でint newCapacity = oldCapacity + (oldCapacity >> 1);見られます。

2. LinkedListの

ArrayListとLinkedListのは、Listインタフェースを実装しますが、LinkedListのは、二重リンクリストの実装です。

パブリック クラス LinkedListは<E>は
     延び AbstractSequentialList <E>
     用具一覧<E>のDeque <E> 、Cloneableを、java.io.Serializableの
{ 
       過渡 INTのサイズ= 0 

    過渡ノード<E> まず、

    過渡ノード<E> 最後。

    パブリックLinkedListの(){ 
        } 

    プライベート 静的 クラスノード<E> { 
            E項目。
            ノード <E> 次; 
            ノード <E> PREV。

        ノード(ノード <E> PREV、E要素、ノード<次){
             この .item = エレメント。
                    この .next = 次回。
                    この .prev = 前; 
                } 
        } 

    ... ... 
}

2.1のArrayListとLinkedListの差

  • トラバーサルは、ループ、foreachのループ、Iteratorインターフェイスのために普通に使用することができます
  • 配列の認識に基づいてのArrayList、LinkedListのベースの二重リンクリスト
  • ArrayListのランダムアクセスと修正の効率は、より効率的なのLinkedListの挿入や削除が比較的高く、

3.ベクトル

ベクターは、スレッドセーフで、同期の多くは、ソースコードから見ることができますがあります。ベクターは、動的配列のスレッドセーフなJavaの以前の読み取り、書き込み動作のシナリオよりもそんなに大きな、外部被ばくのほぼすべてのメソッドのキーワードの変更を同期化、提供され、ベクトルは、システムにパフォーマンスのオーバーヘッドにつながる、ロック競合の多くが発生します。書き込むためには、シーンの読み取りよりも大きくなります

パブリック クラスベクトル<E>は
     延び AbstractList <E>
     用具一覧<E> ランダム・、Cloneableを、java.io.Serializableの
{ 
    ...... 
    保護オブジェクト[]からelementDataします。
    保護された intをし、elementCount。
    保護された int型はcapacityIncrement。

    公共ベクター(INT InitialCapacityの値){
             この(InitialCapacityの値、0 ); 
    } 

    パブリックベクター(){
             この(10 )。
        } 
    
    公共 同期 のint容量(){
             戻りelementData.lengthと、
        } 

    パブリック 同期 int型のサイズ(){
             返すし、elementCountを、
        } 
    ... 
}

ArrayListのとベクトルの違い

 

  • ベクターは、スレッドセーフで、同期されたソースコードの多くが見られますが、することができますがありますArrayListのではありませんだから、より高い性能よりもシングルスレッド、ArrayListのベクトルでは
  • 使用される連続したメモリアレイの基礎となるのArrayListとベクトルは、容量が必要とされる十分な記憶空間が、ArrayListのデフォルトは1.5倍に増加し、ベクトルが2倍に増加既定
  • 使用時間のArrayListとベクトルが同じで、指定された位置データを見つけ、それらは0(1)、ベクターおよびArrayListの缶を使用して、この時間

 

4. CopyOnWriteArrayListと

CopyOnWriteArrayListとは、次の特性があります。

  • 実装Listインタフェース。
  • ()ReentrantLockのロックの内側に=新しいReentrantLockのを保持します。
  • アレイ増加の新しいコピーが、挿入が完了変更または新しいアレイのアレイに割り当てられた操作後に除去されます
  • 追加および削除がロックを取得するために必要な、そして唯一のロック、および読み取りロックを取得する必要はありませんされ、同時サポートしていますニーズへの追加や削除は、操作が完了した後、新しい配列を作成し、元の引用を割り当てるのはなぜ?これは、データを取得していない実行され、読み取り動作を引き起こす可能性のある追加と削除のプロセスに直接元の配列を変更した場合、要素を取得することができ、時間を得ることを確認することです。
  • ReentrantLockの内部使用のスレッドセーフを確保すること。

CopyOnWriteArrayListと方法java.util.concurrentパッケージを実装し、提供されるロックせずに読み出し動作を書き込み動作を、基礎となる配列操作することにより、新たなコピーが、達成される別個の読み取りおよび書き込み同時方式を。 

コピーオンライトその原理は、任意の変更などのポストの追加などの操作、セット、削除は、元の配列をコピーすることで、元の配列、代替スレッドセーフを達成するために、このような防御的な方法を置き換える修正します。

操作を読み書きするために比較的少ない適しており、このデータ構造は非常に、またはコストを変更することは、まだ非常に明白である筆記シーンよりもはるかに大きいを読み取るために適しました

パブリック クラス CopyOnWriteArrayListと<E>
     道具一覧<E> ランダム・、Cloneableを、java.io.Serializableの{
         プライベート 静的 最終 長い serialVersionUIDの= 8673264195747942595L 
    
    / ** すべてのミューテータを保護するロック* / 
    最終 過渡 ReentrantLockのロック= 新しいReentrantLockの(); 
    
    / ** アレイは、唯一のgetArray /はsetArrayを介してアクセスされます。* / 
    プライベート 過渡 揮発性のオブジェクト[]配列。

    パブリック ブール追加(E、E){
             最終 ReentrantLockのロック=このの.lock; 
            lock.lock(); 
            試す{ 
                オブジェクト[]の要素 = のgetArrayを();
                int型のlen = elements.length。
                オブジェクト[]れたnewElements = Arrays.copyOf(要素、LEN + 1 )。
                たnewElements [LEN] = E。
                setArray(たnewElements)。
                返す ; 
            } 最後に{ 
                lock.unlock()。
            } 
        } 
    
    } 

    ... ... 
}

 

おすすめ

転載: www.cnblogs.com/windpoplar/p/11886116.html