Java 集合框架 源码浅析 与理解

这篇博客深入探讨了Java集合框架,重点关注ArrayList、LinkedList和HashMap的源码实现,以及并发安全的集合类。文章详细分析了ArrayList的元素添加逻辑,包括动态扩容和System.arraycopy()的使用。还介绍了LinkedList如何利用链表结构实现高效的插入和删除。HashMap的实现原理,包括JDK1.8中引入的红黑树,以及线程安全的ConcurrentHashMap和CopyOnWriteArrayList。文章总结了集合框架中各种数据结构的优缺点,强调了线程安全和效率的选择。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在研究java源码,就是看一看别人写好的东西,也不算是研究。知根知底的对以后的学习会有很大的帮助,我先去了解一下java集合框架,从总体上对这个组织和操作数据的数据结构有个浅显得的了解。

从网上看了很多资料,发现这一张图总结的还算不错就引用过来了。但是最上面的Map和Collection之间的关系应该是依赖,不是Produces。

一、java集合框架概述

从上面的集合框架图可以看到,Java集合框架主要包括两种类型的容器.

一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射。Collection接口又有3种子类型,List、Set和Queue,再下面是一些抽象类,最后是具体实现类,常用的有ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap等等.

二、Collection接口

首先看一下Collection的结构:

Collection接口是处理对象集合的根接口,其中定义了很多对元素进行操作的方法,AbstractCollection是提供Collection部分实现的抽象类。上图展示了Collection接口中的全部方法。

有几个比较常用的方法,比如方法:

  • add()添加一个元素到集合中,
  • addAll()将指定集合中的所有元素添加到集合中,
  • contains()方法检测集合中是否包含指定的元素,
  • toArray()方法返回一个表示集合的数组。

Collection接口有三个子接口,下面详细介绍。

1.List

List接口扩展自Collection,它可以定义一个允许重复的有序集合,从List接口中的方法来看,List接口主要是增加了面向位置的操作,允许在指定位置上操作元素,同时增加了一个能够双向遍历线性表的新列表迭代器ListIterator。AbstractList类提供了List接口的部分实现,AbstractSequentialList扩展自AbstractList,主要是提供对链表的支持。下面介绍List接口的两个重要的具体实现类,也是我们可能最常用的类,ArrayList和LinkedList。

ArrayList

通过查看ArrayList的源码,我们可以很清楚地看到里面的逻辑,它是用数组存储元素的,这个数组可以动态创建,如果元素个数超过了数组的容量,那么就创建一个更大的新数组(可以看出默认是10个),并将当前数组中的所有元素都复制到新数组中。假设第一次是集合没有任何元素,下面以插入一个元素为例看看源码的实现。

1、方法add(int index, E element) 向集合中指定位置添加指定元素。
  public void add(int index, E element) {
        if (index > size || index < 0)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));

        ensureCapacityInternal(size + 1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        elementData[index] = element;
        size++;
    }
2、此方法主要是确定将要创建的数组大小。
 private void ensureCapacityInternal(int minCapacity) {
        if (elementData == EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }

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

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
3、之后是创建数组,可以明显的看到先是确定了添加元素后的大小之后将元素复制到新数组中。
  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);
    }
4、最后是处理数组,System.arraycopy()可以使用它来实现数组之间的复制,将元素复制到新数组中。
/**
     * The char[] specialized version of arraycopy().
     *
     * @hide internal use only
     */
    public static void arraycopy(char[] src, int srcPos, char[] dst, int dstPos, int length) {
        if (src == null) {
            throw new NullPointerException("src == null");
        }
        if (dst == null) {
            throw new NullPointerException("dst == null");
        }
        if (srcPos < 0 || dstPos < 0 || length < 0 ||
            srcPos > src.length - length || dstPos > dst.length - length) {
            throw new ArrayIndexOutOfBoundsException(
    
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值