Java中ArrayList的remove方法:如何区分按索引和按值删除?
ArrayList中remove(1)的方法区分与实现逻辑
一、JVM怎么区分按索引还是按值删除?
根本上是Java的方法重载机制在编译阶段就确定了调用哪个方法,而非JVM运行时区分。
ArrayList本身提供了两个重载的remove方法:
public E remove(int index):参数是int类型,用于按索引删除元素public boolean remove(Object o):参数是Object类型,用于按值删除第一个匹配的元素
当你写al.remove(1)时,这里的1是int字面量,编译时会优先匹配参数为int的remove方法,也就是按索引删除。如果想调用按值删除的版本,你需要把1显式转为Object类型,比如:
al.remove(Integer.valueOf(1)); // 或者 al.remove((Object) 1);
这样编译时就会匹配Object参数的重载方法,实现按值删除。
二、如何同时实现按索引和按值删除的操作?
如果是自己实现一个类似ArrayList的集合类,只需要通过方法重载提供两个不同参数类型的remove方法即可:
- 按索引删除的方法实现:
public E remove(int index) { // 检查索引是否越界 if (index < 0 || index >= size) { throw new IndexOutOfBoundsException("索引超出范围"); } // 取出要删除的元素 E oldValue = elementData[index]; // 将索引后的元素向前移动一位 int numMoved = size - index - 1; if (numMoved > 0) { System.arraycopy(elementData, index+1, elementData, index, numMoved); } // 清空最后一个位置的引用,减少内存占用 elementData[--size] = null; // 返回被删除的元素 return oldValue; }
- 按值删除的方法实现:
public boolean remove(Object o) { // 区分null值和非null值的匹配逻辑 if (o == null) { for (int index = 0; index < size; index++) { if (elementData[index] == null) { // 找到匹配元素后,调用内部的删除索引方法 fastRemove(index); return true; } } } else { for (int index = 0; index < size; index++) { if (o.equals(elementData[index])) { fastRemove(index); return true; } } } // 没有找到匹配元素,返回false return false; } // 内部复用的索引删除逻辑,省去重复代码 private void fastRemove(int index) { int numMoved = size - index - 1; if (numMoved > 0) { System.arraycopy(elementData, index+1, elementData, index, numMoved); } elementData[--size] = null; }
核心思路就是利用方法重载的特性,通过参数类型的不同,让编译器在编译阶段就确定要调用的方法,从而实现两种不同的删除逻辑。
内容的提问来源于stack exchange,提问作者MCA22 Adarsh Kumar
相关产品推荐
相关产品推荐

