arraylist中set(index,object)与add(index,object)方法的区别

本文详细介绍了集合操作中的set和add方法,解释了它们的功能及使用场景。

set:将原来index位置上的object的替换掉

add:将原来index位置上的向后移动


<think>嗯,用户现在想了解JDK 1.7中ArrayListadd、remove(通过索引和对象)、get和set方法的具体实现和用法。我需要结合之前提供的引用来回答,尤其是引用[3]里关于remove(Object o)的源码分析。不过用户之前的问题和回答主要集中在JDK1.7的特性,所以现在需要详细解释ArrayList这几个核心方法的实现。 首先,我需要确认用户提供的引用内容。引用[1]和[2]是关于JDK1.8的ArrayList构造函数和类定义,而引用[3]是JDK1.7的remove方法源码,包括fastRemove的实现。用户可能误引用了1.8的内容,但问题明确是关于1.7的,所以需要专注于1.7的源码分析。 接下来,用户提到的add、remove(索引和对象)、get和set方法。我需要分别分析每个方法的源码实现,并解释其用法和注意事项。例如,add方法涉及数组扩容,remove通过索引和对象的不同处理,get和set的简单数组访问等。 需要注意的是,JDK1.7和1.8在ArrayList的实现上有一些差异,比如默认容量和初始化方式。根据引用[1],JDK1.8的无参构造函数使用DEFAULTCAPACITY_EMPTY_ELEMENTDATA,而1.7可能有所不同,可能需要查阅1.7的源码确认。不过用户的问题是关于1.7的,所以需要确保引用的源码版本正确。 在回答中,需要将每个方法分开讲解,给出代码示例和源码分析,比如add方法如何检查容量,扩容机制是怎样的(比如增长到原来的1.5倍),remove方法如何移动数组元素,fastRemove的细节,以及通过对象删除时如何遍历和比较元素。此外,还要指出这些方法的时间复杂度和使用时的注意事项,比如并发修改异常等。 另外,用户可能在实际使用中遇到问题,比如在迭代时直接调用remove导致ConcurrentModificationException,这时需要解释fail-fast机制,以及如何正确使用Iterator的remove方法。这些虽然不是直接的方法实现,但属于相关注意事项,对用户有帮助。 最后,生成相关问题时要围绕ArrayList的实现细节、性能优化、线程安全等方面,确保问题有针对性,帮助用户深入理解。</think>以下是对JDK 1.7中`ArrayList`核心方法`add`、`remove`(索引/对象)、`get`和`set`的源码解析及用法说明: --- ### 一、`add`方法实现 #### 1. **添加元素到末尾** ```java public boolean add(E e) { ensureCapacityInternal(size + 1); // 容量检查扩容 elementData[size++] = e; // 尾部插入元素 return true; } ``` - **扩容机制**:当数组已满时,按公式`newCapacity = oldCapacity + (oldCapacity >> 1)`扩容(即1.5倍)[^4] - **示例**: ```java List<String> list = new ArrayList<>(); list.add("Java"); // 首次添加时初始化容量为10 ``` #### 2. **指定位置插入元素** ```java public void add(int index, E element) { rangeCheckForAdd(index); // 索引越界检查 ensureCapacityInternal(size + 1); System.arraycopy(elementData, index, elementData, index+1, size - index); // 元素右移 elementData[index] = element; size++; } ``` - **时间复杂度**:$O(n)$(需要移动元素) - **示例**: ```java list.add(1, "JDK1.7"); // 在索引1处插入元素 ``` --- ### 二、`remove`方法实现 #### 1. **按索引删除** ```java public E remove(int index) { rangeCheck(index); // 索引合法性检查 E oldValue = elementData(index); // 获取被删除元素 int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); // 左移覆盖 elementData[--size] = null; // 置空末尾元素以帮助GC return oldValue; } ``` - **示例**: ```java list.remove(0); // 删除第一个元素 ``` #### 2. **按对象删除**(引用[3]源码) ```java public boolean remove(Object o) { if (o == null) { // 处理null值 for (int index = 0; index < size; index++) if (elementData[index] == null) { fastRemove(index); return true; } } else { // 非null值通过equals比较 for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); return true; } } return false; } private void fastRemove(int index) { modCount++; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // 清理末尾引用 } ``` - **特点**:只删除第一个匹配项,时间复杂度$O(n)$(遍历+移动) - **示例**: ```java list.remove("Java"); // 删除首次出现的"Java" ``` --- ### 三、`get``set`方法 #### 1. **获取元素**(直接数组访问) ```java public E get(int index) { rangeCheck(index); // 索引校验 return elementData(index); // 直接返回数组元素 } ``` - **时间复杂度**:$O(1)$ - **示例**: ```java String item = list.get(0); // 获取第一个元素 ``` #### 2. **修改元素** ```java public E set(int index, E element) { rangeCheck(index); E oldValue = elementData(index); elementData[index] = element; // 直接替换数组元素 return oldValue; } ``` - **示例**: ```java list.set(0, "JDK1.8"); // 替换第一个元素 ``` --- ### 四、关键注意事项 1. **线程不安全**:所有操作未同步,多线程操作需手动加锁或用`Collections.synchronizedList` 2. **快速失败机制**:迭代时修改集合会触发`ConcurrentModificationException`(通过`modCount`校验) 3. **内存优化**:调用`trimToSize()`可释放未使用的数组空间 --- ### 五、性能对比 | 方法 | 平均时间复杂度 | 备注 | |------------|----------------|--------------------------| | `add` | 均摊$O(1)$ | 尾部插入无需移动元素 | | `add(index)` | $O(n)$ | 需要移动后续元素 | | `remove(index)` | $O(n)$ | 同上 | | `remove(Object)` | $O(n)$ | 需遍历+移动 | | `get/set` | $O(1)$ | 直接通过索引访问数组元素 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值