引用ArrayList中的元素,稍后移动

时间:2018-02-23 12:33:27

标签: java arraylist

假设以下代码:

<div id="txtArea" style="width:1000px;">
    <textarea style="margin-left:20px;" class="span1 form-control" rows="6" ></textarea>
</div>
<div id="buttons">
    <input id="btnApprove" type="button"name="action" value="Create Profile" onclick="return validateCreateStaffProfile()" class="btn btn-default btn-sm_Custom active" />
    <input id="btnReject" type="button" style="margin-left: 30px;" class="btn btn-default btn-sm_Custom active" value="Clear" onclick="return ClearStaffProfileActionDiv();" />
    <input id="btnDelete" type="button" name="action" value="Create Profile" onclick="return validateCreateStaffProfile()" class="btn btn-default btn-sm_Custom active" />
</div>

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

我的理论是,不是释放内存和元素引用,而是内存现在指向当前的aList数据,或者在生成数组时更新引用anElement。然而,这两种理论都具有非常糟糕的空间/时间性能含义,因此我认为它们不太可能。

编辑:

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

3 个答案:

答案 0 :(得分:1)

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

您可能需要查看ArrayList here的实施代码,以了解其工作原理的细节&#34;引擎盖&#34;。

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

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

答案 1 :(得分:1)

如果您想了解ArrayList如何在内部工作,只需查看您可以在线找到的来源,例如: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ArrayList.java

在这里,您可以清楚地看到update table_004 t0 set status = 99, bar_date = ( select max(foo_date) AS bar_date from table_001 t1 inner join table_002 t2 on t1.keyA = t2.keyA inner join table_003 t3 on t2.keyA = t3.keyA inner join table_004 t4 on t4.keyB = t3.keyB where t1.id in(1, 2, 3, 4, 5) and t0.keyB = t4.keyB -- added group by t1.id, t4.keyB ) where t0.keyB in (100,101,102,103) -- added 在内部使用,并在视为必要时调整为Object[]

只要您向后面添加内容,索引就会保持不变。如果你在中间插入一些东西,那么后面的元素的所有索引都会增加一个。

答案 2 :(得分:0)

这不是Java,而是给定JVM的实现细节。你可以在这里阅读一些内容:例如https://www.artima.com/insidejvm/ed2/jvm6.html,所以有关于JVM内部的完整书籍 一个简单的方法是拥有一个对象的映射,所以先引用该映射,然后找到实际对象的当前位置。然后,移动实际对象很简单,因为它的地址存储在该地图中的单个副本中 可以说这很慢并且直接存储地址,并且没有在地图中查找对象的额外步骤。这样移动对象将需要更多的工作,尽管仍然可能,只需要更新所有指针(因为原始指针不会出现在语言级别上,暂时转换为数字或存储在一些随机数组中,类似的魔法不能做在这里受到伤害,你总是可以跟踪某个东西是指向你正在移动的对象的指针。)