假设以下代码:
<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>
答案 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内部的完整书籍 一个简单的方法是拥有一个对象的映射,所以先引用该映射,然后找到实际对象的当前位置。然后,移动实际对象很简单,因为它的地址存储在该地图中的单个副本中 可以说这很慢并且直接存储地址,并且没有在地图中查找对象的额外步骤。这样移动对象将需要更多的工作,尽管仍然可能,只需要更新所有指针(因为原始指针不会出现在语言级别上,暂时转换为数字或存储在一些随机数组中,类似的魔法不能做在这里受到伤害,你总是可以跟踪某个东西是指向你正在移动的对象的指针。)