Kotlin,ArrayList的set方法不会替换给定的元素

我正在将子弹移植到kotlin,并编写了运行HelloWorld示例所需的所有东西。

我现在正处于调试阶段,我遇到了对象引用的问题。

一开始,我第一次进入collideTTpersistentStack

 fun collideTTpersistentStack(root0: DbvtNode?, root1: DbvtNode?, collider: DbvtTreeCollider) { if (root0 != null && root1 != null) { var depth = 1 var treshold = DOUBLE_STACKSIZE - 4 val element = StkNN(root0, root1) if (stkStack.isNotEmpty()) stkStack[0] = element else stkStack += element stkStack resize DOUBLE_STACKSIZE do { val p = stkStack[--depth] if (depth > treshold) { stkStack resize (stkStack.size * 2) treshold = stkStack.size - 4 } val pa = pa!! val pb = pb!! if (pa === pb) { if (pa.isInternal) { stkStack[depth++] = StkNN(pa.childs[0], pa.childs[0]) stkStack[depth++] = StkNN(pa.childs[1], pa.childs[1]) stkStack[depth++] = StkNN(pa.childs[0], pa.childs[1]) } } else if (pa.volume intersect pb.volume) if (pa.isInternal) if (pb.isInternal) { stkStack[depth++] = StkNN(pa.childs[0], pb.childs[0]) stkStack[depth++] = StkNN(pa.childs[1], pb.childs[0]) stkStack[depth++] = StkNN(pa.childs[0], pb.childs[1]) stkStack[depth++] = StkNN(pa.childs[1], pb.childs[1]) } else { stkStack[depth++] = StkNN(pa.childs[0], pb) stkStack[depth++] = StkNN(pa.childs[1], pb) } else if (pb.isInternal) { stkStack[depth++] = StkNN(pa, pb.childs[0]) stkStack[depth++] = StkNN(pa, pb.childs[1]) } else collider.process(pa, pb) } while (depth != 0) } } 

但是由于root0null我马上就会退出。 在下一次我输入函数时, root0root1都是有效的对象,它们的引用如下:

 root0 = Dbvt@708 root1 = Dbvt@656 

然后我创建第一个添加到stkStack元素,它仍然是空的,定义如下:

 val stkStack = ArrayList() 

element是如此定义的StkNN类:

 class StkNN(var a: DbvtNode? = null, var b: DbvtNode? = null) 

插入后,我得到:

在这里输入图像说明

这是有道理的。

stkStack resize DOUBLE_STACKSIZE只需创建一些虚拟的StkNN实例

然后我输入do ,然后抓住stkStack的第一个元素,这基本上就是我们刚刚插入的元素:

 p = {Dbvt$StkNN@731} a = {DbvtNode@708} b = {DbvtNode@656} 

然后,我们跳过下一个, if我保存variablespapb作为不可变的检查可空性

 val pa = pa!! val pb = pb!! 

papb在引用方面是一致的:

 pa = @708 pb = @656 

现在我们直接在这里 :

 } else { stkStack[depth++] = StkNN(pa.childs[0], pb) stkStack[depth++] = StkNN(pa.childs[1], pb) } 

depth现在是0stkStack包含一个元素,我们插入在开始,所以它应该取代它与一个新的实例

那么, pa孩子是以下

 pa = {DbvtNode@708} childs = {DbvtNode[2]@748} 0 = {DbvtNode@759} 1 = {DbvtNode@656} 

但是在我完成任务之后, stkStack将包含以下内容:

 stkStack = {ArrayList@709} size = 128 0 = {Dbvt$StkNN@772} a = {DbvtNode@708} // this is wrong, it should be @759 b = {DbvtNode@656} 1 = {Dbvt$StkNN@781} a = {DbvtNode@656} // right b = {DbvtNode@656} // right 

C ++代码使用指针,我仔细检查执行,它的stkStack[0].a指针实际上应该是,就是说,它对应于pa->childs[0]指针

发生什么事?

编辑:如果我在添加实例之前创建一个虚拟对象:

 val test = StkNN(pa.childs[0], pb) stkStack[depth++] = StkNN(pa.childs[0], pb) stkStack[depth++] = StkNN(pa.childs[1], pb) 

它确实有正确的参考,那就是test.a实际上是pa.childs[0] 。 如果我直接分配test

 val test = StkNN(pa.childs[0], pb) stkStack[depth++] = test stkStack[depth++] = StkNN(pa.childs[1], pb) 

stkStack[0] 不是 test ..! 看看set(index: Int, element: Dbvt.stkNN)中的文档set(index: Int, element: Dbvt.stkNN) ,它说:

将此列表中指定位置的元素替换为指定的元素

但是,这不是什么情况

这是我的IDE /项目( 相关 )损坏的东西。 重新克隆项目解决了这个问题

特别感谢downvote&run家伙,这总是一种乐趣