Java 容器篇 List (一)

List

ArrayList

List就是一个动态的数组 如何动态的扩容当容量达到一定阈值的时候会新建一个大容量的数组然后把旧的数组的数据copy到新的数组哪里去。需要注意的new ArrayList如果不带初始化容量的情况 new ArrayList()的时候默认是空的一个数组。只有在操作add的时候才会去初始化一个容量默认为10的数组。

modCount 这个需要注意下 我们知道 java.util.HashMap 不是线程安全的,因此如果在使用迭代器的过程中有其他线程修改了map,那么将抛出ConcurrentModificationException,这就是所谓fail-fast策略。这一策略在源码中的实现是通过modCount域,modCount 顾名思义就是修改次数,对HashMap内容的修改都将增加这个值,那么在迭代器初始化过程中会将这个值赋给迭代器的expectedModCount。在迭代过程中,判断modCount 跟 expectedModCount是否相等,如果不相等就表示已经有其他线程修改了 Map:注意到 modCount声明为 volatile,保证线程之间修改的可见性。 modCount到底是干什么的呢 所以使用在循环中删除同一个list的元素的时候需要好好对待,分分给你抛异常,尽量使用迭代器吧。

	// ArrayList扩容的代码
    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);
    }

foreach中删除异常出现错误的原因(modCount的原因)
foreach只是java语言的语法糖,本质上还是由Iterator来迭代的,但在删除时,调用的是list的remove方法,正是这里引发了修改异常。

ArrayList小结:在使用arrayList的时候如果可以大概知道数组的长度返回建议指定大小,避免数组copy的消耗。

CopyOnWriteArrayList

CopyOnWriteArrayList出来的原因就是一个线程安全的一个ArrayList,
只有作为共享list的时候才考虑使用,所有安全的东西是比较慢的。

线程安全的原理直接贴代码其实根据它的名字大概也可以猜测出多少东西复制然后再写入的一个ArrayList(取名很优秀)add的方法都要上一把锁ReentrantLock锁整个过程了,这个代码很简单易懂,优秀。

    public boolean add(E e) {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
        	// 获取当前的数组
            Object[] elements = getArray();
            // 获取当前数组的长度
            int len = elements.length;
            // 把当前数组的所有元素复制到一个新的数组里面去然后操作
            Object[] newElements = Arrays.copyOf(elements, len + 1);
            // 把最后一个位置给要添加的元素
            newElements[len] = e;
            // 把当前对象的数据指向新的数组
            setArray(newElements);
            return true;
        } finally {
            lock.unlock();
        }
    }

CopyOnWriteArrayList小结:就是写入操作的时候加锁具体看代码。

Vector

这个玩意跟ArrayList就是一个东西来的只是加了synchronized 全部都加了 get add 都加了 重的很一般不用这个玩意。

附录

接口名称作用
Listlist容器接口
RandomAccess支持随机访问
Cloneable支持克隆
java.io.Serializable支持序列化

参考文献

java集合遍历的几种方式总结及比较
modCount到底是干什么的呢

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值