ArrayList和LinkedList实现

Java基础,ArrayList和LinkedList在实际中已经使用很多了,探究一下他的底层实现。

ArrayList源码

ArrayList继承自AbstractList继承自AbstractCollectionAbstractCollection实现了接口Collection

参见源码,由Object[] elementData数组实现。new ArrayList<Integer>()调用无参构造默认是一个空数组,当add时才向其中添加数据。数组扩容,默认长度是10,超过10之后按原容量的1.5倍扩容。

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
	transient Object[] elementData; 
	
	private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}
    
    private static final int DEFAULT_CAPACITY = 10;
	
	//空参构造
	public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
    
    private void add(E e, Object[] elementData, int s) {
        if (s == elementData.length)
            elementData = grow();
        elementData[s] = e;
        size = s + 1;
    }
    //常用的添加
    public boolean add(E e) {
        modCount++;//fast-fail
        add(e, elementData, size);
        return true;
    }
    
    private Object[] grow(int minCapacity) {
        return elementData = Arrays.copyOf(elementData,
                                           newCapacity(minCapacity));
    }
    
    private int newCapacity(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);//扩大为原来的1.5倍
        if (newCapacity - minCapacity <= 0) {
            if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
                return Math.max(DEFAULT_CAPACITY, minCapacity);
            if (minCapacity < 0) // overflow
                throw new OutOfMemoryError();
            return minCapacity;
        }
        return (newCapacity - MAX_ARRAY_SIZE <= 0)
            ? newCapacity
            : hugeCapacity(minCapacity);
    }
    //扩容
    private Object[] grow() {
        return grow(size + 1);
    }

}

fast-fail

在add 中出现了modCount++,在 AbstractList中定义,

/*子类对该字段的使用是可选的。 如果一个子类希望提供快速失败的迭代器(和列表迭代器),那么它只需要在其 add(int, E) 和 remove(int) 方法(以及它覆盖的任何其他导致结构 列表的修改)。 对 add(int, E) 或 remove(int) 的单个调用必须向该字段添加不超过一个,否则迭代器(和列表迭代器)将抛出虚假的 ConcurrentModificationExceptions。 如果实现不希望提供快速失败的迭代器,则可以忽略此字段。*/

    protected transient int modCount = 0;

补充一个快速失败(fast-fail)迭代器是什么意思。

在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加、删除、修改),则会抛出Concurrent Modification Exception。每当迭代器使用hashNext()/next()遍历下一个元素之前,都会检测modCount变量是否为expectedmodCount值,是的话就返回遍历;否则抛出异常,终止遍历。

java.util包下的集合类都是快速失败的,不能在多线程下发生并发修改(迭代过程中被修改)。

LinkedList源码

LinkedList继承自 AbstractSequentialList继承自 AbstractList继承自 AbstractCollection,实现了接口 Collection

链表形式

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
    transient int size = 0;

    /**
     * Pointer to first node.
     */
    transient Node<E> first;

    /**
     * Pointer to last node.
     */
    transient Node<E> last;
    
    
    /**
     * Constructs an empty list.
     */
    public LinkedList() {
    }  

    //默认尾插
    public boolean add(E e) {
        linkLast(e);
        return true;
    }
    
    //尾插
    void linkLast(E e) {
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }
}

参考 ConcurrentHashMap & HashtableArrayList

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值