JAvaソース解析——ArrayList

4565 ワード

JAvaソース解析——ArrayList
  • 一継承と実現
  • 二ArrayListの内部解析
  • ArrayListはその名の通り「配列集合」
    継承と実現
  • まずこのArrayListクラスの中でどのクラスとインタフェースextends AbstractList implements List,RandomAccess,Cloneable,javaを継承し実現したかを見てみましょう.io.Serializable
  • はAbstractListを継承し,AbstractListでは既にListインタフェース内の方法が実現されている.継承は、AbstractListのaddメソッドのような親を強化するためのいくつかの方法であることを知っています.彼は異常を投げただけで、他の操作をしていません.私たちのArrayListはこのaddメソッドを使用しているに違いありません.だから、ArrayListの中で親を書き換えるこの方法です.なぜAbstractList addメソッドが例外だけを投げ出して操作しないのかというと、addの操作が許可されていない集合があるからです.例えば、修正できない集合を呼び出すと、このUnsupportedOperationException異常を投げます.ここでは開発者の設計思想を示した.
  • 次にListインタフェースを実現しましたなぜabstractListが実現したのか疑問ですなぜここで以下のListを実現したのか親を直接書き直せばいいのではないでしょうか.この操作は何の目的ですか.arraylistの目標はリストを実現することだと明らかにする意向があると思います.AbstractList抽象クラスを拡張するのはその目標を実現する方法の一つにすぎません.結局AbstractListはいくつかの方法を実現しました.私は何をしますか.それとも一度やりますか.ハハハ.
  • RandomAccess Cloneable java.io.Serializableこれらのインタフェースはあまり知られていないはずです.

  • 二ArrayListの内部解析
  • ArrayListでは主にObjectタイプの配列、elementDataを維持しています.
  • デフォルト容量は10-DEFAULT_CAPACITY = 10.
  • の3つの構築方法1つ目:デフォルトの構築方法はelementDataを直接DEFAULTAPACITY_に割り当てます.EMPTY_ELEMENTATAは空の配列の2番目である:initialCapacityの初期化を受け入れる容量が0より大きいとnew Object[initialCapacity];0に等しい場合は、空の配列が0より小さい場合にカスタム例外情報Illegal Capacityを放出します.3つ目は、Collection extends E>を受け入れて、このパラメータtoarrayをelementDataに割り当てます.このelementDataの長さが0でなければ、objectタイプの配列かどうかを判断します.そうでなければ、elementDataがobjタイプの配列ではない場合、elementDataがobjクラスの配列に変わります.なぜソースコードに注釈//c.toArray might(incorrectly)not return Object[](see 6260652)は、伝達されたパラメータが配列に変換された後、Object[]に戻らない可能性があるため、Object[]に変換しなければならないという意味です.0に等しい場合は、デフォルトの空の配列を与えます.

  • メソッドtrimToSize:このArrayListインスタンスの容量*リストの現在のサイズをトリムします.アプリケーションは、*ストレージArrayListインスタンスを最小化するためにこの操作を使用できます.
         public void trimToSize() {
            modCount++;//       
            //           ArrayList   size            size。
            if (size < elementData.length) {
            //size 0                copy   size            elementData。
                elementData = (size == 0)
                  ? EMPTY_ELEMENTDATA
                  : Arrays.copyOf(elementData, size);
            }
        }
        
    

    方法ensureCapacityInternalの目的は容量を計算して確保するここでArrayList成長の計算アルゴリズム彼の容量成長公式はint newCapacity=oldCapacity+(oldCapacity>>1)である.わあ、数学者のプログラマーになりたくないのはいい運転手ではない数学が重要だ.
     private void ensureCapacityInternal(int minCapacity) {
     //  elementData                      10                                           
            if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
                minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
            }
              //       
            ensureExplicitCapacity(minCapacity);
        }
    
        private void ensureExplicitCapacity(int minCapacity) {
        //         
            modCount++;
    
            // overflow-conscious code                    0           
            if (minCapacity - elementData.length > 0)
                grow(minCapacity);
        }
    
     private void grow(int minCapacity) {
            // overflow-conscious code         
            int oldCapacity = elementData.length;
            //                       1.5      ?           https://stackoverflow.com/questions/4450628/arraylist-how-does-the-size-increase
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            if (newCapacity - minCapacity < 0)
                newCapacity = minCapacity;
            if (newCapacity - MAX_ARRAY_SIZE > 0)
                newCapacity = hugeCapacity(minCapacity);
            // minCapacity is usually close to size, so this is a win:
            elementData = Arrays.copyOf(elementData, newCapacity);
        }
    
        private static int hugeCapacity(int minCapacity) {
            if (minCapacity < 0) // overflow
                throw new OutOfMemoryError();
            return (minCapacity > MAX_ARRAY_SIZE) ?
                Integer.MAX_VALUE :
                MAX_ARRAY_SIZE;
        }
    

    メソッドcontainsは、1つのelementパラメータがこの集合の中でこの実装されているかどうかを判断する方法は、ループ配列がこの対応するelementのindexを見つけ、indexが存在する場合はtrueメソッドindexofを返し、このelementパラメータを見つけたindex、すなわち、上述したループ配列が値を探しているindexがnullオブジェクトがこのnullを見つけた位置であればindexを返すことである.
     public int indexOf(Object o) {
            if (o == null) {
                for (int i = 0; i < size; i++)
                    if (elementData[i]==null)
                        return i;
            } else {
                for (int i = 0; i < size; i++)
                    if (o.equals(elementData[i]))
                        return i;
            }
            return -1;
        }
    

    メソッドlastIndexOfはindexofとは正反対のループでsizeからi-
    方法toArrayこれは簡単ですcopyofを呼び出してelementDataを再コピーしてtoarrayに戻るTタイプの配列原理があるのと同じです