从源码角度分析Java容器


持续更新中~~

ArrayList

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
	private static final int DEFAULT_CAPACITY = 10; //默认容量
}

ArrayList是基于数组实现的,实现了RandomAccess接口表明该类支持快速随机访问。RandomAccess中只有一个空接口(从下面的注释可以看出此接口主要是为了让实现它的类支持随机访问)

/**
 * Marker interface used by <tt>List</tt> implementations to indicate that
 * they support fast (generally constant time) random access.  
...**/
public interface RandomAccess {
}

构造函数

private static final Object[] EMPTY_ELEMENTDATA = {};//用于空实例的共享空数组实例
//We distinguish this from EMPTY_ELEMENTDATA to know how much to inflate whenfirst element is added.
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//用于空实例的共享空数组实例(用于默认容量)

/**
这个数组是动态扩展的,并不是所有的空间都被使⽤,因此就不需要所有的内容都被序列化。
通过重写序列化和反序列化⽅法,使得可以只序列化数组中有内容的那部分数据。
*/
transient Object[] elementData; //transient关键字可以使⼀些属性不会被序列化

private int size; //数组大小
//Constructs an empty list with the specified initial capacity.
//ArrayList<String> list = new ArrayList<String>(10);
public ArrayList(int initialCapacity) {
    if (initialCapacity > 0) {
        this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {
        this.elementData = EMPTY_ELEMENTDATA;
    } else {
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    }
}
//Constructs an empty list with an initial capacity of ten.
//ArrayList<String> list = new ArrayList<String>();
public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
//Constructs a list containing the elements of the specifiedcollection, 
public ArrayList(Collection<? extends E> c) {
    Object[] a = c.toArray();
    if ((size = a.length) != 0) {
        if (c.getClass() == ArrayList.class) {
            elementData = a;
        } else {
            elementData = Arrays.copyOf(a, size, Object[].class);
        }
    } else {
        // replace with empty array.
        elementData = EMPTY_ELEMENTDATA;
    }
}

添加元素:添加元素时使⽤ ensureCapacityInternal() ⽅法来保证容量⾜够,如果不够时,需要使⽤ grow() ⽅法进⾏扩容,新容量的⼤⼩为 oldCapacity + (oldCapacity >> 1) ,即 oldCapacity+oldCapacity/2。其中 oldCapacity >> 1 需要取整,所以新容量⼤约是旧容量的 1.5 倍左右。(oldCapacity 为偶数就是1.5 倍,为奇数就是 1.5 倍-0.5)

public boolean add(E e) {
    ensureCapacityInternal(size + 1);
    elementData[size++] = e; //在末尾添加元素
    return true;
}
//使⽤ensureCapacityInternal()⽅法来保证容量⾜够
public void ensureCapacity(int minCapacity) {
   int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) ? 0 : DEFAULT_CAPACITY;
   if (minCapacity > minExpand) {
       ensureExplicitCapacity(minCapacity);
   }
}
private void ensureExplicitCapacity(int minCapacity) {
    modCount++;
    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}
//使⽤ grow() ⽅法进⾏扩容
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);
    //扩容操作需要调⽤ Arrays.copyOf() 把原数组整个复制到新数组中,这个操作代价很⾼,因此最好在创建 ArrayList 对象时就指定⼤概的容量⼤⼩,减少扩容操作的次数。
}

删除元素:需要调⽤ System.arraycopy() 将 index+1 后⾯的元素都复制到 index 位置上,该操作的时间复杂度为O(N),可以看到 ArrayList 删除元素的代价是⾮常⾼的。

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

modCount

  • 前面的代码多次出现modCount++这行代码,这是为了来记录 ArrayList 结构发⽣变化的次数。结构发⽣变化是指添加或者删除⾄少⼀个元素的所有操作,或者是调整内部数组的⼤⼩,仅仅只是设置元素的值不算结构发⽣变化。
  • 在进⾏序列化或者迭代等操作时,需要⽐较操作前后 modCount 是否改变,如果改变了需要抛出ConcurrentModificationException

Vector

LinkedList

CopyOnWriteArrayList

HashMap

ConcurrentHashMap

LinkedHashMap

WeakHashMap

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值