一、ArrayListに
1.1のArrayListについて
ArrayListには、動的に成長し、Listインタフェースを実装してインデックスシーケンスを、縮小することができ、Listインタフェースは、また、Collectionインタフェースを継承しています。すべてのタイプのデータを格納することができ、基礎となる配列、配列要素のタイプオブジェクトタイプ、すなわち、によって達成されます。
ArrayListクラスのインスタンスの基礎となる当社の業務の全てを配列に基づいています。
1.2継承
1.3概要ポイント
それは、包括的かつ詳細な文書を書きたい、理解することを学ぶが、辞書とそのどのような違いを考えるの自然作るのですか?彼らの質問に答えるために、ソースコードや他の情報と組み合わせる工程で発生した、独自のソースコードを読み取り、いくつかの興味深い小さなについてはこちらを記録し、その後、この方法は、直接確認するために行っていないが、彼らは原理を理解する必要があります。
どのようなメンバ変数と1.ArrayListクラスが持つ属性?
1 / * 2 10 *デフォルトの容量 3。 * / 4 プライベート 静的 最終 int型 DEFAULT_CAPACITY = 10 ; 5 / ** 6 *空のオブジェクト配列 7。 * / 8。 プライベート 静的 最終オブジェクト[] EMPTY_ELEMENTDATA = {}; 9 * /デフォルトのヌルオブジェクトアレイ 10 プライベート 静的 最終オブジェクト[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; 11 アレイの* /要素 12は 、過渡のオブジェクト[]からelementData; // 簡単にするために、非ネストされたクラスの専用アクセス 13 * /実際の要素のサイズは、デフォルト値は0である 14 専用 のint サイズ; 15 アレイの* /最大容量 16 プライベート 静的 最終 INT。MAX_ARRAY_SIZE Integer.MAX_VALUEの= - 8。
私は2つの質問があり、ここを参照してください:
(1)ここでは、オブジェクトの空の配列との違いは何ですかオブジェクトのデフォルトの空の配列は、なぜ2つの空の配列に従事しますか?
:読み取り元に構成後者の方法は、あなたがはっきりと見ることができます
プライベート 静的 最終オブジェクト[] EMPTY_ELEMENTDATA = {};
ヌル・オブジェクト・メソッドは、パラメータの配列を構築するために使用され、この方法は、指定された入力が0である場合に指定された初期容量、初期容量が、そのようなオブジェクトの空の配列を返す有する空の配列を構築します
プライベート 静的 最終オブジェクト[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
引数なしで空のオブジェクトコンストラクタのデフォルトの配列は、このメソッドを呼び出すと、それは、オブジェクト10の空の配列のデフォルトの初期容量を返します。
アレイの理由(2)最大容量は MAX_ARRAY_SIZE = Integer.MAX_VALUEの- 8。 ?
A:8の配列の必要性は、独自のサイズ(2,147,483,648)を(2 ^ 31)を格納するためにバイト、ソースコードの他にも、コメントに書い
配列内のタイトル文字の一部を保持するためにいくつかの仮想機会。より大きなアレイを割り当てる試みのOutOfMemoryエラーが発生することがあります。要求された配列のサイズが制限仮想マシンを超えます
2.ArrayListはどのように作成するのですか?
ソースCCPは3つのコンストラクタが用意されています。
引数なしで(1)コンストラクタ:
/ ** * 10の初期容量で空のリストを作成します。 * / 公共のArrayList(){ この .elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA。 }
そこコンストラクタのパラメータ(2)指定された容量:
/ ** *初期容量指定された構成を有する空のリストは、 * * @param 初期容量InitialCapacityの値リストは * @throws 初期容量が負の場合、IllegalArgumentExceptionを受信スロー * * / 公共のArrayList(INT InitialCapacityの値){ IF( InitialCapacityの値> 0 ){ この .elementData = 新しい新しいオブジェクト[InitialCapacityの値]; } そう IF(InitialCapacityの値== 0 ){ この .elementData = EMPTY_ELEMENTDATA; } 他{ 投 新しいはIllegalArgumentException( "不正な容量:" + InitialCapacityの値)。 } }
(3)コレクションを含む要素のリストを指定するように構成されました
/ ** *指定の要素を含むリストを作成し 、それらをコレクションのによって返される順序で、*コレクションを *イテレータ。 * * @param 要素リスト内に配置される収集C * @throws 指定されたコレクションがnullである場合NullPointerExceptionが * / 公共のArrayListは、(コレクション<?延び E> {c)は からelementData = c.toArray()。 場合((サイズ= elementData.length)!= 0 ){ // (不正に)c.toArrayのかもしれないが、オブジェクトが返されない[](6260652を参照してください) もし(!。elementData.getClass()=オブジェクト[] クラス) からelementData = Arrays.copyOf(。からelementData、サイズ、オブジェクト[] クラス)。 } 他{ // 空の配列と交換してください。 この .elementData = EMPTY_ELEMENTDATA。 } }
3.ArrayListは、動的な拡張を実現する方法ですか?
一つの文章、次のとおりです。
(配列の要素の新しい長さを加えた後、である)が必要とされる総容量は、元の最大容量よりも大きい場合に要素を追加する前のArrayListは、比較され、拡張、新しい容量= 1.5 *古い容量であろう
追加要素の下から、ArrayListのを参照するにはステップバイステップでは、どのような時、どのように展開するのです。
開始:インデックスの指定したインデックスにある要素の要素を追加
公共 ボイド追加(INT インデックス、E要素){ rangeCheckForAdd(インデックス); //添字範囲チェック ensureCapacityInternalを(サイズ。+ 1); //はmodCountのプロセスを増加させながら、必要な容量増加及び拡張のサイズを決定します値!! System.arraycopyの(インデックスのからelementData、,. 1 +インデックスからelementData 、 サイズ - 指数); // [インデックス]のからelementData = エレメント; サイズ ++ ; }
(1)添字範囲チェック
/ ** *アドオンとのaddAllで使用rangeCheckのバージョン。 * / プライベート 無効 rangeCheckForAdd(int型のインデックス){ 場合(インデックス>サイズ||インデックス<0 ) スロー 新しいはIndexOutOfBoundsException(outOfBoundsMsg(インデックス)); }
現在の配列要素+1の数は、本明細書に新しい長さと呼ばれる:(2)最低限必要な容量の成長、渡されたパラメータ値を決定します
公共 のボイド ensureCapacity(int型minCapacityに){ int型 minExpand =(からelementData =!DEFAULTCAPACITY_EMPTY_ELEMENTDATA) // 任意のサイズ表要素のデフォルト以外の場合 0?// それが0を返す場合は、空のテーブルを // ないデフォルト値10に戻ります空のテーブル :DEFAULT_CAPACITY。IF(minCapacityに>するminExpand){ ensureExplicitCapacity(minCapacityにすること); } } プライベート静的INT calculateCapacity(のオブジェクト[]からelementData、INT {minCapacityにすること) 最小容量//計算は、元の配列が空の場合、必要な最小容量に戻り、必要10のデフォルト値
//元の配列が空でない場合、それは入ってくる新しい長さ(元の数よりも大きい配列要素)を返す IF(==のからelementData DEFAULTCAPACITY_EMPTY_ELEMENTDATA){ 返す(minCapacityにすること、DEFAULT_CAPACITY)Math.maxを; } リターンminCapacityにすること; } プライベート ボイド ensureCapacityInternal(INT minCapacityにすること){ ensureExplicitCapacity(calculateCapacity minCapacityにすること、の(からelementData)); } プライベート ボイド ensureExplicitCapacity(INT minCapacityにすること){ ModCount ++ ; // この新しい長さは、配列の長さより大きい場合、ダイナミックな成長のためにgroww()メソッドを使用して IF( minCapacityに- elementData.length> 0) )(minCapacityにを育てます。 }
(3)元の配列入ってくる新しい長さ値の拡張
/ ** *の能力の増加は、ことを確認HOLD IT CANで少なくとも 最小容量引数でで指定されたの*ナンバー要素。 * * @Param 所望の最小容量でminCapacityに * / プライベート のボイド(グロウのint minCapacityに){//受信新しい長さのパラメータ(元の配列内の要素の数+1)の値 // オーバーフロー配慮コード INT oldCapacity = elementData.length; INT newCapacity oldCapacity + =(oldCapacity >> 1。); 1.5容量のため//新しい=古い容量* IF(newCapacity -であるminCapacityに<0 )膨張した後、新しい容量がまだ新しい容量の成長は、新たな長さの値に等しくなった後に必要な最小容量よりも小さい場合// newCapacity =minCapacityにすること; IF(newCapacity - MAX_ARRAY_SIZE> 0 )//拡張後、新しい容量が最大容量よりも大きい場合、新しい長さの値のサイズが新しいの容量に応じて決定 newCapacity = (minCapacityにすること)hugeCapacity; // minCapacityにはSO、閉じるサイズに通常ことこの勝利である: =のからelementData Arrays.copyOf(のからelementData、newCapacityを); } プライベート 静的 int型(hugeCapacity INT minCapacityに){ IF(minCapacityに<0)// 配列の要素の元の数が既にInteger.MAX_VALUEで、int型のminCapacityにある場合負の数と相まってあふれる 投球 新新)(OutOfMemoryErrorが発生し、 リターン?新しい長さが最大容量よりも大きい場合(minCapacityに> MAX_ARRAY_SIZEは)//、新しい容量にInteger.MAX_VALUEと等価である、または最大容量に等しい Integer.MAX_VALUEの: MAX_ARRAY_SIZE; }
(4)新たな可変長配列、特定の要素が挿入され、加えて配列内の要素の数に元の配列要素をコピー
4.役割modCount変数は、より多くのソースコードがあるで何度も表示されるとは何ですか?
ソースは親クラスAbstractListのint型の定義属性で見つけることができます参照してください:modCount、構造変化のArrayListの数を記録します。
protected transient int modCount = 0;
()、削除()、のaddAll()、removeRange()を追加し、クリア()メソッド:メソッドのすべての両方の構造変化を伴う値であって、ArrayListのmodCountを加えました。これらのメソッドのそれぞれを呼び出して、値が1つのmodCount増加しています
modCountは主スレッドにわたって反復されることを防止、マルチスレッド環境で使用する必要があり、別のスレッドが(等追加および削除要素、ソーティングを含む)は、このリストの構造を変更します。リストが横断されると、イテレータは例外がスローされます変更します。ConcurrentModificationExceptionを
ArrayListのは、我々はスレッドセーフではありませんデータ構造をトラバースときに、イテレータを利用するために、非スレッドセーフであります