JAva jdk 8ソース解析のutilパッケージ:list集合クラスソース分析

7207 ワード

List集合は秩序ある集合として,ユーザがリスト内の要素の位置をよく把握し,整数のインデックスによりリストから所望のデータを取得できる.
1.Collection
collectionクラスは集合の中で基本的なインタフェースであり、1つの集合はこのオブジェクトのグループを表し、一部の集合は秩序正しく無秩序であり、jdkはCollectionインタフェースからの直接的な実装を提供していない.リストやsetなどのより多くのサブインタフェースの実装を提供しているので、このインタフェースは集合の最大の汎用性を保証するために設定されている.彼の方法名は主に次のとおりです.
int size();

boolean isEmpty();

boolean contains(Object o);

Iterator iterator();

Object[] toArray();  //    

boolean add(E e);

boolean remove(Object o);


 2.ArrayList
サイズ変更可能な配列であり、List(Collectionサブインタフェース)インタフェースを継承し、list操作の大部分を実現し、null値を含むすべてのタイプの要素と重複値を挿入することができる.基本操作のほか、内部配列サイズを制御する方法も多く、スレッド同期ではない.クラス継承は以下の通りである.
public class ArrayList extends AbstractList
        implements List, RandomAccess, Cloneable, java.io.Serializable{

  transient Object[] elementData;   //     Object  

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

拡張方法を主に分析します.
  private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {  //         ,        
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

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

        //                       
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
  private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1); //  1/2
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)  //             (   int    )     
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity); //        
    }

removeメソッド
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])) {  //  equals      
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }

    /*
     * Private remove method that skips bounds checking and does not
     * return the value removed.
     */
    private void fastRemove(int index) {
        modCount++;
        int numMoved = size - index - 1;  //         
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index, 
                             numMoved);  //  arraycopy        
        elementData[--size] = null; // clear to let GC do its work
    }

getメソッド
   public E get(int index) {
        rangeCheck(index);  //  index      

        return elementData(index);
    }

  E elementData(int index) {
        return (E) elementData[index]; //        
    }

ソースコードから,追加操作は削除操作よりも時間的複雑度が小さく,追加はO(1),削除はO(n),コンテナの拡張と削除要素はcopyofとarrycopyメソッドを呼び出し,下位層はc++を実現するため効率が高いことが分かる.コンテナの容積は限られており、最大値はintタイプの最大値である.
2.LinkList
ダブルチェーンテーブル構造に属し、ListとDequeインタフェースを継承し、空の値を含む任意の値と重複値を挿入できます.
public class LinkedList
    extends AbstractSequentialList
    implements List, Deque, Cloneable, java.io.Serializable
{
    transient int size = 0;  //  

    transient Node first;  //       

    transient Node last;  //        


    private static class Node {
        E item;
        Node next; //     
        Node prev;  //     

        Node(Node prev, E element, Node next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }


....
}

Deque:デュアルチェーンテーブルの操作方法を定義し、サブクラスの汎用性を向上
AbstraactSequentialList:この抽象クラスは、このインタフェースを実装するワークロードを低減するためのフレームワークの実装を提供し、リストを順次格納する実装に適しています.
addメソッド
public boolean add(E e) {
        linkLast(e);  //      
        return true;
    }

 void linkLast(E e) {
        final Node l = last;
        final Node newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null) //       
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }

removeメソッド
 public boolean remove(Object o) {
        if (o == null) {  
            for (Node x = first; x != null; x = x.next) {
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
            for (Node x = first; x != null; x = x.next) {
                if (o.equals(x.item)) {
                    unlink(x);
                    return true;
                }
            }
        }
        return false;
    }

 E unlink(Node x) { //x       
        // assert x != null;
        final E element = x.item;
        final Node next = x.next;
        final Node prev = x.prev;

        if (prev == null) { //           
            first = next;
        } else {
            prev.next = next;  
            x.prev = null;
        }

        if (next == null) { //            
            last = prev;
        } else {
            next.prev = prev;
            x.next = null;
        }

        x.item = null;  //       
        size--;
        modCount++;
        return element;
    }

getメソッド
 public E get(int index) {
        checkElementIndex(index);
        return node(index).item;
    }

 Node node(int index) {
        // assert isElementIndex(index);

        if (index < (size >> 1)) {  //  index          
            Node x = first;
            for (int i = 0; i < index; i++)  //    
                x = x.next;
            return x;
        } else {
            Node x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }

linklistクラスで、内部は双方向チェーンテーブル構造です.チェーンテーブル内のnodeオブジェクトごとに、前後の要素の参照が保存されます.チェーンテーブルの両端に挿入削除を行うことができます.それ以外は容量に制限されません.配列要素は無限に複数あります(仮想マシン構成に関連しています).クエリーでは、比較的線形テーブルを最初から最後から巡回する必要があります.
3.Vector
同期バージョンのArrayListクラスは,ArrayList実装の原理とほぼ同じである.唯一の違いは、Vectorがスレッドで安全であることです.主なadd方法は以下の通りである.
 public synchronized boolean add(E e) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);  //        
        elementData[elementCount++] = e;
        return true;
    }

以上がリスト集合に対する私の理解です.