java - 对 ArrayList 中稍后移动的元素的引用

标签 java arraylist

假设以下代码:

ArrayList<A> aList = new ArrayList<>();
for(int i = 0; i < 1000; ++i) 
    aList.add(new A());
A anElement = aList.get(500);
for(int i = 0; i < 100000; ++i) 
    aList.add(new A());

之后 anElement 仍然正确引用 aList[500],即使 ArrayList 在第二个 for 循环期间可能多次重新分配其数据。这个假设是否不正确?如果不正确,Java 如何设法让 anElement 仍然指向内存中的正确数据?

我的理论是,要么不是释放 anElement 引用的内存,而是该内存现在指向当前 aList 数据,要么在增长数组时更新 anElement 的引用。然而,这两种理论都对空间/时间性能产生了非常糟糕的影响,所以我认为它们不太可能。

编辑:

我误解了数组如何存储元素,我以为它们直接存储它们,但实际上它们存储引用,这意味着 anElement 和 aList[500] 都指向堆上的某个对象,解决了我无法理解的问题!

最佳答案

当内部存储 ArrayList 元素的数组变满时,将创建更大的新数组,并将前一个数组中的所有元素复制到相同索引处的新数组中,现在有新元素的空间。垃圾收集器将删除以前不再需要的数组。

您可能想看一下 ArrayList 的实现代码 here查看其“幕后”工作原理的详细信息。

代码中的第二个循环,在第 1000 个元素之后添加了接下来的 100000 个元素,因此现在 aList 中有 101000 个元素,前 1000 个元素没有移动到任何地方。使用 get() 方法,您只能读取该元素,不会从该 ArrayList 中移动或删除任何内容。

请注意,ArrayList 并不像数组那样工作(例如 A 数组是 A[]),而且它不是固定的-size 集合 - ArrayList 在添加或删除元素时更改其大小 - e。 G。如果删除索引 0 处的元素 (aList.remove(0);),则存储在索引 1000 处的元素现在存储在索引 999 处,并且 ArrayList 的大小也存储在索引处从 1000 更改为 999。

关于java - 对 ArrayList 中稍后移动的元素的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48948013/

相关文章:

使用 ArrayList<Object> 的 Android Parcelable 实现

java - ArrayList 添加空指针

java - 无法在 JTable 中返回 Double 值

java - ClassNotFoundException : com. mysql.jdbc.Driver gradle 无法解析

java - 在 Java 中如何判断最终用户是否有声卡?

Java 迭代类的集合并使用它们的函数

java - ArrayList在自定义列表类Java中实现

java - 如何访问 Guava 多重映射的所有值?

java - 从多个客户端更新服务器上对象的模式/最佳实践

java - java 将 int 值追加到空数组中