ArrayListの基本原則とインタビューの回答

機能:基になるデータ構造は配列であり、順序付けされており、スレッドは安全ではありません。

配列--->検索と追加および合計テーブルの長さはO(1)、要素の挿入と削除はO(n)です。

初期化サイズは10で、拡張メカニズムは元の配列の長さの1.5倍に拡張することです。

 

スレッドの安全でないコードは次のことを反映しています。

// List<String> testArray = new ArrayList<>(); 抛ConcurrentModificationException(并发修改)异常
// List<String> testArray = new Vector<>(); //线程安全,低效(Synchronized)
// List<String> testArray = Collections.synchronizedList(new ArrayList<>()); //线程安全,低效(Synchronized) 
List<String> 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(); //释放锁
    }
}

 

CopyOnWriteArrayList関連クラスには、概念が含まれます。

深いコピーと浅いコピー:

  1. 浅いコピー:値を基本データ型に渡し、参照データ型を参照してコピーします。これは浅いコピーです。
  2. ディープコピー:基本データ型の値を渡し、参照データ型の新しいオブジェクトを作成し、そのコンテンツをコピーします。これはディープコピーです。

 

コアコードには多くのコピー操作があります

System.arraycopy()およびArrays.copyOf()メソッド

2つの方法の違いは何ですか?

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> T[] copyOf(T[] original, int newLength) {
    return (T[]) copyOf(original, newLength, original.getClass());
}         

 

拡散の関連知識ポイント:

HashSetの最下層はHashMapですが、HashSetはHashMapのキーのみを受け取り、Valueの値は一律にObject定数に設定されます。

LinkedListの基礎となるデータ構造:二重にリンクされたリスト

 

元の記事を27件公開しました 賞賛されました0 訪問9933

おすすめ

転載: blog.csdn.net/weixin_38246518/article/details/105519146