JDK源码-Collection-add()以及addAll()

本文解析了Java Collection接口中默认不支持单个元素添加的原因,并详细介绍了add(E e)方法及addAll(Collection<? extends E> c)方法的工作原理。文章强调了子类如需支持元素添加,必须自行实现add(E e)方法。

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

Add
Collection 中默认不支持添加单个元素,如果直接调用 add(E) 方法,会报错:

public boolean add(E e) {
    throw new UnsupportedOperationException();
}

因此,如果子类是可添加的数据结构,需要自己实现 add(E) 方法。


AddAll

public boolean addAll(Collection<? extends E> c) {
    boolean modified = false;
    for (E e : c)
        if (add(e))
            modified = true;
    return modified;
 }

挨个遍历,调用 add() 方法添加,因此如果没有实现 add(E) 方法,addAll() 也不能用

<think>好的,我现在需要解析JDK-8u201中List接口的源码,特别是addaddAll方法的工作原理,以及它们在AbstractCollection中的未实现部分。首先,我得回忆一下Java集合框架的结构。List接口继承自Collection接口,而AbstractList作为List的抽象实现类,提供了部分方法的默认实现。但用户提到的是AbstractCollection中的addaddAll方法,所以可能需要先查看AbstractCollection源码。 根据引用[1],AbstractCollection中的addAll方法有默认实现,引用了addAll(c)的实现。这可能意味着AbstractCollection提供了addAll的通用实现,而add方法可能没有实现,需要子类重写。比如ArrayList这样的具体类必须实现add方法,而addAll可能直接使用AbstractCollection中的实现。 接下来,我需要确认JDK8u201中AbstractCollection源码。AbstractCollection是一个抽象类,实现了Collection接口。它的add方法默认抛出UnsupportedOperationException,因为不同的集合可能有不同的添加元素的方式,比如有些集合不支持添加操作。而addAll方法则是通过循环调用add方法来实现的,这样如果add方法没有被正确实现,addAll也会抛出异常。 比如,在AbstractCollection中,add方法的默认实现是抛出异常,而addAll方法会遍历传入的集合,逐个调用add方法添加元素。因此,如果子类没有重写add方法,调用addAll时也会失败。例如,在不可变集合中,如Collections.emptyList(),调用addaddAll都会抛出异常,因为它们的add方法没有实现。 然后,List接口本身并没有直接实现这些方法,而是由AbstractList来提供进一步的实现。例如,AbstractList可能提供了add(int index, E element)的默认实现,但依然可能抛出异常,除非子类如ArrayList覆盖了这些方法。例如,ArrayList的add方法会在数组末尾添加元素,并在需要时扩容。 用户的问题还涉及到未实现的逻辑。比如,AbstractCollection中的add方法没有具体实现,需要子类处理具体的添加逻辑。如果子类没有实现add,调用时会直接抛出异常。而addAll方法虽然有一个默认实现,但它依赖于add方法,因此如果add未实现,addAll也无法正常工作。 可能需要具体查看JDK8u201的源码来验证这些点。例如,AbstractCollectionadd方法确实默认抛出异常,而addAll方法遍历集合元素并逐个调用add。因此,任何继承AbstractCollection的集合类如果想支持add操作,必须重写add方法,否则无法使用addaddAll。 此外,引用[2]提到了ArrayList的源码解析,其中详细说明了addaddAll的实现,包括扩容机制。而引用[3]涉及到Collection接口中的方法,如stream()和parallelStream(),这可能与迭代方式有关,但当前问题更关注addaddAll的实现。 总结来说,需要明确AbstractCollectionaddaddAll的默认行为,以及List接口中这些方法的具体实现情况。特别是哪些部分需要子类实现,哪些已经提供了默认实现,以及这些方法在未实现时的异常抛出机制。</think>### JDK-8u201 List接口源码解析:add/addAll方法实现分析 #### 一、AbstractCollection中的默认行为 1. **`add(E e)`方法** 在`AbstractCollection`中,`add`方法默认抛出`UnsupportedOperationException`: ```java public boolean add(E e) { throw new UnsupportedOperationException(); } ``` 这是因为不同类型的集合(如不可变集合)可能不支持添加操作,需要子类根据需求重写[^1]。 2. **`addAll(Collection<? extends E> c)`方法** `AbstractCollection`提供了`addAll`的默认实现: ```java public boolean addAll(Collection<? extends E> c) { boolean modified = false; for (E e : c) if (add(e)) // 依赖子类实现的add方法 modified = true; return modified; } ``` 该方法通过遍历集合`c`,逐个调用`add(e)`实现元素添加。若子类未实现`add`方法,调用`addAll`时会抛出异常[^1]。 --- #### 二、List接口与AbstractList的实现 `List`接口继承自`Collection`,其核心方法(如`add(int index, E element)`)在`AbstractList`中部分实现: 1. **`add(int index, E element)`方法** `AbstractList`默认抛出异常,因为需要子类处理索引逻辑: ```java public void add(int index, E element) { throw new UnsupportedOperationException(); } ``` 具体实现类如`ArrayList`会覆盖此方法以支持动态数组的插入[^2]。 2. **批量添加`addAll`的重载方法** `AbstractList`未直接实现`addAll(int index, Collection<? extends E> c)`,但`ArrayList`通过以下步骤实现: - 检查索引范围 - 扩容数组(若需要) - 移动元素并插入新集合 - 最终调用`System.arraycopy`完成高效操作。 --- #### 三、未实现逻辑与子类责任 1. **`add`方法未实现场景** - 若子类(如`Collections.unmodifiableList`)未重写`add`方法,调用时会直接抛出异常。 - 示例: ```java List<String> immutableList = Collections.emptyList(); immutableList.add("test"); // 抛出UnsupportedOperationException ``` 2. **`addAll`的依赖关系** 即使子类未重写`addAll`,其默认实现依然依赖`add`方法。例如: ```java List<String> list = new AbstractList<>() { private final String[] data = {"a", "b"}; @Override public String get(int index) { return data[index]; } @Override public int size() { return data.length; } }; list.addAll(List.of("c", "d")); // 抛出异常,因未实现add ``` --- #### 四、具体实现类分析(以ArrayList为例) 1. **`add(E e)`方法** 源码核心逻辑: ```java public boolean add(E e) { ensureCapacityInternal(size + 1); // 检查并扩容 elementData[size++] = e; // 尾部插入元素 return true; } ``` 扩容机制:当数组容量不足时,新容量扩展为旧容量的1.5倍[^2]。 2. **`addAll(Collection<? extends E> c)`方法** 实现步骤: - 将集合`c`转换为数组 - 计算所需最小容量 - 扩容并批量拷贝元素 - 时间复杂度为$O(n + m)$(n为原列表长度,m为新集合长度)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值