从底层设计分析List和Set区别

List和Set区别最直观的List是有序可重复,Set无序不可重复

但是3年以上工作更注重的是底层数据结构与算法。

List最常用的是ArrayList(可变长度的动态数组)

ArrayList源码中指定transient (不能被序列化)修饰的Object[] ,就是个数组。

注意:正常使用中是可以序列化的,因为ArrayList重写了readObject、writeObject方法

(1)
/**
 * The array buffer into which the elements of the ArrayList are stored.
 * The capacity of the ArrayList is the length of this array buffer. Any
 * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
 * will be expanded to DEFAULT_CAPACITY when the first element is added.
 */
transient Object[] elementData; // non-private to simplify nested class access

ArrayList有三种构造器:(这里只说无参构造)

(2)
public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

ArrayList会有默认的DEFAULTCAPACITY_EMPTY_ELEMENTDATA,下方注释也说了只有在第一次添加才知道数组大小是多少。

(3)
/**
 * Shared empty array instance used for default sized empty instances. We
 * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
 * first element is added.
 */
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

接下来直接看add

(4)
public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // 注意每次添加是size+1
    elementData[size++] = e;
    return true;
}

继续跟进ensureCapacityInternal(size + 1);

(5)
private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}

继续调用方法,先看calculateCapacity(elementData, minCapacity);//计算容量

(6)
private static int calculateCapacity(Object[] elementData, int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//前边知道了这里第一次肯定相等
        return Math.max(DEFAULT_CAPACITY, minCapacity);// 取默认值和传进来的minCapacity=1取最大值;DEFAULT_CAPACITY默认是10
    }
    return minCapacity;
}

知道初始容量为10,返回去看(5)ensureExplicitCapacity

(7)
private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)// 第一次相减大于0
            grow(minCapacity);
    }

接着才是真的初始化容量

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);
}

Set常用的就是HashMap/TreeMap

TreeSet内部就是

private transient NavigableMap m;

你可能感兴趣的:(面试常见问题)