深java8コレクション:の原則のArrayListの実現

  I.概要

  さあ、このソースコード内のコメントで見てみましょうが、我々はいくつかの重要な情報を抽出することができます。

  Listインタフェースのサイズ変更可能な配列の実装。リストの任意のオペレーションをすべて実装し、nullを含め、すべての要素を、許可します。Listインタフェースを実装することに加えて、このクラスは、リストを格納するために内部的に使用される配列のサイズを操作するための方法を提供します。(このクラスは、それが同期していないことを除いて、ベクトルとほぼ同等です。)

  このコメントから、我々はArrayListのがnullを含むすべての要素の挿入を可能と関連するすべてのメソッドは、動的配列、実現Listインタフェースやリストであることがわかります。さらに、ArrayListのとベクトル外部スレッドに加えて、実質的に等しく同期していません。

  第二に、財産

  //デフォルトサイズの容量

  プライベート静的最終int型のDEFAULT_CAPACITY = 10;

  //空の配列定数

  プライベート静的最終的なオブジェクト[] EMPTY_ELEMENTDATA = {};

  //デフォルトの空の配列定数

  プライベート静的最終的なオブジェクト[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

  このArrayListのから//ストレージアレイ要素は、基礎となる実装に見ることができるオブジェクトの配列であります

  一時オブジェクト[]からelementData。

  配列に含まれる要素の数//

  プライベートint型のサイズ。

  上限//配列

  プライベート静的最終int型のMAX_ARRAY_SIZE = Integer.MAX_VALUEの - 8。

  ArrayListのプロパティは、これらの、非常に小さいです。最も重要なの一つは、すべてのメソッドは、からelementData上に構築されてからelementData、ArrayListのです。次に、我々はそれの主な方法のいくつかを見てみましょう。

  第三に、この方法

  1、工法

  公共のArrayList(INT InitialCapacityの値){

  IF(InitialCapacityの値> 0){

  this.elementData新しいオブジェクトを= [InitialCapacityの値]。

  }そうであれば(InitialCapacityの値== 0){

  this.elementData = EMPTY_ELEMENTDATA。

  }他{

  新しいはIllegalArgumentException( "不正な容量:" + InitialCapacityの値を)投げます。

  }

  }

  公共のArrayList(){

  this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA。

  }

  私たちは、からelementData空の配列のサイズは初期サイズは、我々は初期サイズを指定してからelementDataなったとき、我々は初期サイズを指定すると0で、デフォルトでは、コンストラクタから見ることができます。

  2、getメソッド

  公共E GET(int型のインデックス){

  rangeCheck(インデックス)。

  リターンからelementData(インデックス);

  }

  プライベート無効rangeCheck(int型のインデックス){

  もし(インデックス> =サイズ)

  新しいはIndexOutOfBoundsException(outOfBoundsMsg(インデックス))を投げます。

  }

  EからelementData(INTインデックス){

  リターン(E)からelementData [インデックス]。

  }

  ArrayListには、構造体のアレイの使用が格納されているので、それは方法が範囲外である場合、最初の決定、非常に簡単であり得るので、そう時間複雑度はO(1)で取得し、配列の添字を介して直接素子を得ることができます。

  3、addメソッド

  パブリックブールの追加(E電子){

  ensureCapacityInternal(サイズ+ 1)。//インクリメントmodCount !!

  elementData [サイズ++] = E。

  trueを返します。

  }

  公共のボイドの追加(int型のインデックス、Eの要素){

  rangeCheckForAdd(インデックス)。

  ensureCapacityInternal(サイズ+ 1)。//インクリメントmodCount !!

  //複製方法のネイティブを呼び出し、要素インデックスの開始位置は1背面に移動されています

  System.arraycopyの(からelementData、インデックスからelementData、指数+ 1、サイズ - インデックス)

  elementData [インデックス] =要素;

  サイズ++;

  }

  プライベート無効ensureCapacityInternal(int型minCapacityに){

  IF(からelementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA){

  minCapacityに= Math.max(DEFAULT_CAPACITY、minCapacityに)。

  }

  ensureExplicitCapacity(minCapacityに)。

  }

  プライベート無効ensureExplicitCapacity(int型minCapacityに){

  modCount ++;

  もし(minCapacityに - elementData.length> 0)

  (minCapacityに)成長。

  }

  ArrayListのAddメソッドは、要素を挿入する前に、さらによく理解されて容量が必要であるかどうかを最初にチェックし、次に最後の要素の後に配列に要素を追加します。ensureCapacityInternal方法では、我々が見ることができ、場合、いつからelementData空の配列は、それが拡張にデフォルトのサイズを使用しています。コンストラクタパラメータでのArrayListを作成するときに、そのサイズのみが成長法によりサイズ10の配列を作成するために、時間のみを使用するように、実際にはゼロです。

  Oの第一の方法の追加の複雑さ(1)、時には操作の拡張を含むが、しかし、拡張の数は非常に小さいので、時間のこの部分は無視できます。指定したAddメソッドを有する被験体を使用している場合、複雑さはO(N)であり、それは配列内の要素の移動を伴うため、この操作は非常に時間がかかります。

  図4に示すように、設定された方法

  パブリックEセット(INTインデックス、E要素){

  rangeCheck(インデックス)。

  E OLDVALUE =からelementData(インデックス)

  elementData [インデックス] =要素;

  OLDVALUEを返します。

  }

  メソッド・セット・アクションは非常に似てgetで、要素要素に添字インデックスを交換することで、そう、時間計算量O(1)の度合いを繰り返すことはしません。

  5、removeメソッド

  公共Eのremove(int型のインデックス){

  rangeCheck(インデックス)。

  modCount ++;

  E OLDVALUE =からelementData(インデックス)

  int型numMoved =サイズ - インデックス - 1。

  (numMoved> 0)であれば

  System.arraycopyの(からelementData、指数+ 1、からelementData、インデックス、numMoved)。

  elementData [ - サイズ] = NULL; GCはその作業をやらせるために//をクリア

  OLDVALUEを返します。

  }

  主題の方法は、方法は、要素のarraycopyシステムを動かすために起動され、指定されたメソッドで追加および削除に非常に類似しているが、時間複雑度はO(N)です。

  6、方法を育てます

  プライベートのボイドが成長(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)。

  } 鄭州その婦人科良いの病院で治療http://www.120kdfk.com/

  この方法は、私たちが見ることができるから、アレイの拡張は、ArrayListのが毎回展開が1.5倍に拡大し、その後copyOfメソッド配列クラスを呼び出すされたときに、行くために新しい配列に要素を再コピーに使用される成長。

  図7に示すように、サイズメソッド

  公共int型のサイズ(){

  サイズを返します。

  }

  サイズメソッドは、それが直接、戻り値の大きさであり、非常にシンプルである配列内の要素の数を返す、時間複雑度はO(1)です。ここでは、返される配列の実際のサイズではありません、注意しなければなりません。

  8、indexOfメソッドとのlastIndexOf

  公共のintのindexOf(オブジェクトo){

  IF(O == NULL){

  以下のために(; I <サイズ; int型私は0を= I ++)

  (からelementData [I] == NULL)場合

  私は返します。

  }他{

  以下のために(; I <サイズ; int型私は0を= I ++)

  IF(o.equals(からelementData [I]))

  私は返します。

  }

  -1を返します。

  }

  公共INTのlastIndexOf(オブジェクトo){

  IF(O == NULL){

  以下のために(INT iが、サイズ= 1; I> = 0; i--)

  (からelementData [I] == NULL)場合

  私は返します。

  }他{

  以下のために(INT iが、サイズ= 1; I> = 0; i--)

  IF(o.equals(からelementData [I]))

  私は返します。

  }

  -1を返します。

  }

  アクションのindexOf方法は、第1の要素が校正値に等しい返すことです。それは見つけるために、配列の各要素の値を比較することによってトラバースされる、その時間複雑度はO(N)です。

  indexOfのようなのlastIndexOfでも、原則として、それだけで何も見つけないために戻ってから始めています。

  ベクター

  ベクトルArrayListの多くの同じに関連する方法が、賃金はより多くのスレッドの安全性を確保するための同期。これでベクトルとArrayListの表情の異なる点は、だから。

  ベクトルのArrayListより1つの多い属性:

  capacityIncrementだけintを保護。

  このプロパティは、展開時に使用されている、それだけのスペースが十分ではcapacityIncrementを展開する時間展開を表します。この属性は、コンストラクタによってそれに割り当てることができます。コンストラクタで最初に見て:

  公共ベクター(INT InitialCapacityの値、INTはcapacityIncrement){

  スーパー();

  (InitialCapacityの値<0)の場合

  新しいはIllegalArgumentException( "不正な容量:" + InitialCapacityの値を)投げます。

  this.elementData新しいオブジェクトを= [InitialCapacityの値]。

  this.capacityIncrement = capacityIncrementだけ。

  }

  公共ベクター(INT InitialCapacityの値){

  この(InitialCapacityの値、0);

  }

  パブリックベクター(){

  この(10)。

  }

  コンストラクタから、我々はベクトルのデフォルトのサイズは10であることがわかりますし、それが作成された配列の初期化であり、これは、ArrayListのと同じではありません。そして、グロー方法を見てみましょう。

  プライベートのボイドが成長(int型minCapacityに){

  //オーバーフローを意識したコード

  int型oldCapacity = elementData.length。

  int型newCapacity = oldCapacity +(?(capacityIncrementだけ> 0)はcapacityIncrement:oldCapacity)。

  もし(newCapacity - minCapacityに<0)

  newCapacity = minCapacityに。

  もし(newCapacity - MAX_ARRAY_SIZE> 0)

  newCapacity = hugeCapacity(minCapacityに)。

  elementData = Arrays.copyOf(からelementData、newCapacity)。

  }

  私たちが成長プロセスから見ることができ、newCapacityのデフォルトは2倍oldCapacity、とはcapacityIncrementの値が指定されたとき、newCapacityはoldCapacity + capacityIncrementだけになりました。

  概要

  図1に示すように、作成したArrayListの0の大きさ、最初の要素に加え、第一の時間展開のために、10のデフォルトサイズの容量。

  2、ArrayListの各拡張は、現在の膨張アレイの1.5倍の大きさです。

  図3は、デフォルトのサイズは、Vectorは10を作成したとき。

  4、ベクトル拡張は、現在の拡張に、アレイの各2倍の大きさです。capacityIncrementだけを指定する場合、各拡張は、元の基準空間のはcapacityIncrement単位を高めます。

  5、ArrayListのとベクトルを追加、取得、メソッドのサイズの複雑さはO(1)は、削除方法の複雑さはO(N)です。

  図6は、ArrayListには、非スレッドセーフで、ベクターは、スレッドセーフです。

おすすめ

転載: www.cnblogs.com/djw12333/p/12067249.html