ArrayList、LinkedList、HashMap區(qū)別

首先問的是ArrayList和LinkedList的區(qū)別。

先看ArrayList的相關(guān)源碼:

private static final int DEFAULT_CAPACITY = 10;
transient Object[] elementData;

可以看出ArrayList底層是實現(xiàn)了一個Object數(shù)組,并且初始容量為10

private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        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);
    }

可以看出ArrayList動態(tài)擴(kuò)容是原本的1.5倍,而且擴(kuò)容是把原本的數(shù)據(jù)復(fù)制到新的數(shù)組,這樣很耗費時間,所以一般在建arraylist的時候,可以把數(shù)據(jù)長度定義為預(yù)想的1.5倍,這樣就可以免去擴(kuò)容導(dǎo)致的復(fù)制問題

public void add(int index, E element) {
        rangeCheckForAdd(index);

        ensureCapacityInternal(size + 1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        elementData[index] = element;
        size++;
    }
public E remove(int index) {
        rangeCheck(index);

        modCount++;
        E oldValue = elementData(index);

        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }

在看ArrayList的插入和刪除,都需要移動后面的元素,比較耗時

再看LinkedList的代碼

public boolean add(E e) {
        linkLast(e);
        return true;
    }
public void add(int index, E element) {
        checkPositionIndex(index);

        if (index == size)
            linkLast(element);
        else
            linkBefore(element, node(index));
    }
 public boolean remove(Object o) {
        if (o == null) {
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item)) {
                    unlink(x);
                    return true;
                }
            }
        }
        return false;
    }
public int indexOf(Object o) {
        int index = 0;
        if (o == null) {
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null)
                    return index;
                index++;
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item))
                    return index;
                index++;
            }
        }
        return -1;
    }

可以看到LinkedList的插入和刪除其實也是需要通過for循環(huán)查找到具體位置的,所以并不一定比ArrayList的刪除插入快。

再看HashMap的源碼

這題答得比較爛,其實是了解的,我們先來看源碼

DEFAULT_INITIAL_CAPACITY =16 默認(rèn)容量為
MAXIMUM_CAPACITY =1 << 30 最大容量為
DEFAULT_LOAD_FACTOR = 0.75f 默認(rèn)負(fù)載因子
TREEIFY_THRESHOLD=8 鏈表轉(zhuǎn)換紅黑樹的閥值
UNTREEIFY_THRESHOLD=6 紅黑樹轉(zhuǎn)換鏈表的閥值
MIN_TREEIFY_CAPACITY=64 桶中bin最小hash容量,如果大于這個值會進(jìn)行

總結(jié):

  1. 一個是數(shù)組實現(xiàn),一個是鏈表實現(xiàn)。
  2. ArrayList可以快速查詢,鏈表需要遍歷。ArrayList插入刪除需要移動元素,鏈表只需要改變節(jié)點指向就行
  3. ArrayList內(nèi)存不足時需要動態(tài)擴(kuò)容,每次是原來的1.5倍,LinkedList不需要動態(tài)擴(kuò)容
  4. 這一題回答的時候,動態(tài)擴(kuò)容以及插入刪除的效率沒有說出來
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容