假设我正在尝试从头开始实现Java的ArrayList
。我知道我会使用称为数组的数据结构,必须在需要时扩展其容量,并跟踪大小(数组中的项目数)和数据(数组的内容)之类的东西。
由于有这个大小的实例变量,当我们从ArrayList
中删除某些内容,例如从2, 3, 4, 5
中删除4时,我们将剩下2, 3, 5, [empty space]
,对吗?据我所知,我们将设置等于下一个元素的值,因此实际上不缩小数组的大小,仅在需要时才对其进行扩展。
如果我的问题不清楚,我只是在寻找remove(Object element)
的{{1}}实现。
我希望有一张图表来解释。如果还有其他需要,请询问。谢谢。
答案 0 :(得分:1)
当我为2016年的GATE(工程学能力测验)考试做准备时,我对 C 语言也有类似的疑问。
好吧,从那时起我增强了编码技能,现在我用Java进行编码。
根据List API
删除此列表中指定位置的元素(可选 操作)。将所有后续元素向左移动(减去一个 从他们的索引)。返回从中删除的元素 列表。
ArrayList
类是List
接口的基于数组的实现。具体来说,ArrayList
的所有元素都存储在Java数组中。
Arraylist.remove(E)
的实现如下:
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // Let gc(garbage collector) do its work
return oldValue;
}
elementData
是支持元素数组。
换句话说,它并没有太大的变化,因为它是元素的副本,减去元素的丢失。
将elementData
赋予4个元素
[ 2 | 3 | 4 | 5 ]
现在删除索引2处的元素
导致 [2 | 3 | 5 | null]
ArrayList.get(2)
将导致 5
答案 1 :(得分:0)
这很简单,并解释了为什么计划不删除最后一个元素时不使用ArrayList
保留。
ArrayList
有2个部分:内部数组(默认大小为10-ArrayList.DEFAULT_CAPACITY = 10
)和 size 值(默认值为0
。
注意1。。当您可以预测ArrayList
的最大大小时,请将内部数组初始化为该大小。
List<String> list1 = new ArrayList<>(); // size = 0, internal array Object[] elementData = new Object[10];
List<String> list2 = new ArrayList<>(66); // size = 0, internal array Object[] elementData = new Object[66];
在最后添加元素
size == elementData.length
->创建更大的新elementData
并将所有现有数据复制到此新数组中size++
(数组末尾有许多null
元素)从最后删除元素
size > 0
)size--
从开头或中间删除元素
size--
如您所见,ArrayList
的大小和内部数组elementData
的长度之间没有直接关联。
演示:
List<String> list = new ArrayList<>(4); // [ null | null | null | null ], size = 0
list.add("2"); // [ "2" | null | null | null ], size = 1
list.add("3"); // [ "2" | "3" | null | null ], size = 2
list.add("4"); // [ "2" | "3" | "4" | null ], size = 3
list.add("5"); // [ "2" | "3" | "4" | "5" ], size = 4
list.remove(3); // [ "2" | "3" | "5" | null ], size = 3
list.remove(1); // [ "3" | "5" | null | null ], size = 2