java基础の容器(一)ArayList底の原理と面接の回答

3037 ワード

特徴:下のデータ構造は配列である.順序がよいスレッドが不安定です
配列-->検索と追加、および表の長さを求めるのはO(1)で、削除要素を挿入するのはO(n)です.
初期化サイズは10で、拡大機構は元の配列長の1.5倍に拡大する.
 
スレッドの不安全コードの表現:
// List testArray = new ArrayList<>();  ConcurrentModificationException(    )  
// List testArray = new Vector<>(); //    ,  (Synchronized)
// List testArray = Collections.synchronizedList(new ArrayList<>()); //    ,  (Synchronized) 
List testArray = new CopyOnWriteArrayList<>();
//     ,ReentrantLock     ,  ,       1   ,           ,       (          )
for (int i = 0; i < 50 ; i++) {
    new Thread(()-> {
        testArray.add("aaa");
        System.out.println(testArray);
    },String.valueOf(i)).start();
}
/**
 * Replaces the element at the specified position in this list with the
 * specified element.
 * CopyOnWriteArrayList             
 * @throws IndexOutOfBoundsException {@inheritDoc}
 */
public E set(int index, E element) {
    final ReentrantLock lock = this.lock;
    lock.lock(); //   
    try {
        Object[] elements = getArray();
        E oldValue = get(elements, index);

        if (oldValue != element) {
            int len = elements.length;
            //      
            Object[] newElements = Arrays.copyOf(elements, len);
            newElements[index] = element;
             //         
            setArray(newElements);
        } else {
            // Not quite a no-op; ensures volatile write semantics
            setArray(elements);
        }
        return oldValue;
    } finally {
        lock.unlock(); //   
    }
}
 
CopyOWriteArayList関連クラスは、概念に関連する:
深度コピーと浅いコピー:
  • コピー:基本データタイプを値転送し、参照データタイプを参照転送するようにコピーします.これは浅いコピーです.
  • 深度コピー:基本データタイプを値転送し、参照データタイプを新たなオブジェクトを作成し、その内容を深くコピーする.
  •  
    コアコードに大量のコピー操作があります.
    System.arraycopy()とArays.co pyOf()の方法
    二つの方法にはどんな違いがありますか?
    System.arraycopy()ターゲット配列が必要です.オリジナルの配列を自分で定義した配列にコピーして、コピーの起点と長さと新しい配列に入れる位置を選択できます.
    copyOf()は、システムが自動的に内部に新しい配列を作って、その配列を返します.
     /**
     * @param      src      the source array.    
     * @param      srcPos   starting position in the source array.          
     * @param      dest     the destination array.       
     * @param      destPos  starting position in the destination data.     
     * @param      length   the number of array elements to be copied.     
     */
    public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);
                                        ...  
                                        
    /**
    * original       ;newLength       
    */                                    
    public static  T[] copyOf(T[] original, int newLength) {
        return (T[]) copyOf(original, newLength, original.getClass());
    }         
     
    拡散に関する知識点:
    HashSetの下の階はhashMapです.HashSetはHashMapのKeyだけを取って、Valueの値はObjectの定数に統一されます.
    Linked List下のデータ構造:双方向リンク表