我有一个包含对象引用的数组。我想将数组中的一些引用更改为另一个对象。目前我使用的循环如下所示:
for (int i = region2.getStartPos(); i <= curPos; i++) {
if (regions[i] == region2) {
regions[i] = region1;
}
}
我想避免使用for循环,因为它会增加计算复杂性。
有没有办法让region2
引用的对象直接等于region1
?
例如,我尝试在Region
类中编写一个方法,如下所示,但它给了我一个“无法为最终变量赋值”错误。
public void mergeRegions(Region region){
this = region;
}
这样的事情可能吗?
答案 0 :(得分:1)
Java中的每个引用都只是内存中某个对象的地址,因此如果没有一些额外的代码,就无法实现所要求的“自动更新”。
想象一下,region1
引用内存中的地址0x1001
,region2
引用0x2001
。这两个存储器位置保存实际区域数据:
0x1001
:x = 0, y = 5, width = 20, height = 30
0x2001
:x = 100, y = 200, width = 50, height = 20
如果你能以某种方式告诉0x2001
上的对象等于0x1001
,那么使用你的mergeRegions
方法,Java会尝试这样做吗?
0x1001
:x = 0, y = 5, width = 20, height = 30
0x2001
:0x1001
但这不起作用,因为Java对象都应该是Region
个对象,每个对象都有相同的字段和方法。如果我们在0x2001
消灭了Java对象,并且只是放入一个普通的地址,那么0x2001
的任何现有引用都不起作用,因为它们都期望Region
个对象在那个地址。这就是为什么你不能“直接将”一个Java引用分配给另一个。
以下三个提示可帮助您重新设计算法:
0x1001
中的所有数据复制到0x2001
的对象中,而不是将地址0x1001
复制到0x2001
。这将使两个对象等效,但是分开。regions
数组将包含对IndirectRegion
个对象的引用,这些对象将依次保存对实际Region
对象的引用。如果您要将region2
更新为region1
,则只需要求其中一个IndirectRegion
个对象更新其内部参考。答案 1 :(得分:0)
你不能这样做,因为它会违反该对象对其他呼叫者的行为方式。你的第一个for循环是你能做的最好的。更好的解决方案可能是不使用数组而是使用具有O(1)访问权限的东西。例如,Set<T>
。你可以像
set.remove(region2);
set.add(region1);
如果你写了.equals()
和.hashcode()
另一个解决方案是将所有内容从一个类复制到另一个类。我不确定我对此的感受以及它是否安全。但是你可以做类似的事情。
public void mergeRegions(Region region){
this.a=region.a;
this.b=region.b;
this.c=region.c;
this.d=region.d;
}
答案 2 :(得分:0)
你在使用数组是为了什么?我也想到了Amir和Dan关于交换内容或使用间接的建议。但我觉得你应该改变你的数据结构。那么请您详细说明阵列的用法吗?
例如,如果您只有几个区域n,那么可能不使用区域对象数组,您可以使用n组整数并使用联合,交集和补充或交换集等集合操作。或者你甚至不再需要整数,但可以使用EnumSets或EnumMaps。
如果您碰巧有Josh Bloch的书“Effective Java”,请查看关于数组的第25项和关于EnumSets / EnumMaps的第32/33项。