【源码分析】Java集合框架源码分析(三)

先来看看集合Collection的继承关系图:
在这里插入图片描述

Collection接口主要分为三类:List、Set、Queue。
List:有序、有下标、可重复
Set:无序(LinkedHashSet除外)、无下标、无重复
Queue:队列

ArrayList用的比较多,可以做个详细的讲解。
LinkedList实现了List接口和Deque接口,底层采用链表实现,下标查询和插入比较慢,优点是作为队列。
Vector和Stack是同步容器,单线程用的话比较慢,底层是数组实现的。
HashSet底层采用的是HashMap来实现的。value是一个final Object,因为移除的时候可以判断是否移除成功。

public boolean remove(Object o) {
        return map.remove(o)==PRESENT;
    }

LinkedHashSet底层采用的LinkedHashMap来实现的。
TreeSet底层采用的是TreeMap来实现。

其实List和Set都比较简单。下面来看看Queue。Queue下面有双端队列Deque、阻塞队列BlockingQueue。

  • add 增加一个元索 如果队列已满,则抛出一个IIIegaISlabEepeplian异常
  • remove 移除并返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
  • element 返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
  • offer 添加一个元素并返回true 如果队列已满,则返回false
  • poll 移除并返问队列头部的元素 如果队列为空,则返回null
  • peek 返回队列头部的元素 如果队列为空,则返回null
  • put 添加一个元素 如果队列满,则阻塞
  • take 移除并返回队列头部的元素 如果队列为空,则阻塞

下面的表格很明显:
在这里插入图片描述

4.1 ArrayBlockingQueue

ArrayBlockingQueue是一个有边界的阻塞队列,它的内部实现是一个数组。有边界的意思是它的容量是有限的,我们必须在其初始化的时候指定它的容量大小,容量大小一旦指定就不可改变。

ArrayBlockingQueue是以先进先出的方式存储数据,最新插入的对象是尾部,最新移出的对象是头部。

4.2 LinkedBlockingQueue

LinkedBlockingQueue阻塞队列大小的配置是可选的,如果我们初始化时指定一个大小,它就是有边界的,如果不指定,它就是无边界的。说是无边界,其实是采用了默认大小为Integer.MAX_VALUE的容量 。它的内部实现是一个链表。

和ArrayBlockingQueue一样,LinkedBlockingQueue 也是以先进先出的方式存储数据,最新插入的对象是尾部,最新移出的对象是头部。

4.3 PriorityBlockingQueue

PriorityBlockingQueue是一个没有边界的队列,它的排序规则和 java.util.PriorityQueue一样。需要注意,PriorityBlockingQueue中允许插入null对象。

所有插入PriorityBlockingQueue的对象必须实现 java.lang.Comparable接口,队列优先级的排序规则就是按照我们对这个接口的实现来定义的。

4.4 SynchronousQueue

SynchronousQueue队列内部仅允许容纳一个元素。当一个线程插入一个元素后会被阻塞,除非这个元素被另一个线程消费。

4.5 DelayQueue

getDelay()方法的返回值就是队列元素被释放前的保持时间,如果返回0或者一个负值,就意味着该元素已经到期需要被释放,此时DelayedQueue会通过其take()方法释放此对象。


一、ArrayList详解

  1. 默认数组长度10,每次扩容size的一半 int newCapacity = oldCapacity + (oldCapacity >> 1)
  2. 当元素满了的时候,再添加新元素就会触发扩容
    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);
    }
  1. 用迭代器遍历的时候,如果并发修改容器的元素,就会抛异常。这个也叫做快速失败。
        final void checkForComodification() {
        	//modCount  ArrayList的成员变量,每次修改的时候,都会+1 
        	//expectedModCount 创建迭代器的时候,modCount的值
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值