开发者

How do i change multiple references at once in Java?

I have an array holding references for objects. I want to change some of those references in开发者_运维问答 the array to another object. At the moment I use a for loop like the one below:

for (int i = region2.getStartPos(); i <= curPos; i++) {        
    if (regions[i] == region2) {
        regions[i] = region1;
    }
}

I want to avoid the for loop though, because it increases the computational complexity.

Is there a way to make the object referenced by region2 equal to the one of region1 directly? For example, I have tried writing a method in the Region class like the one below, but it gives me a "cannot assign a value to final variable this" error.

public void mergeRegions(Region region){
    this = region;
}

Is something like this possible?


Each reference in Java is simply an address to some object in memory, so the kind of "automatic updates" you're asking for require aren't possible without some extra code.

Imagine that region1 references the address 0x1001 in memory, and region2 references 0x2001. These two memory locations hold the actual region data:

  • 0x1001: x = 0, y = 5, width = 20, height = 30
  • 0x2001: x = 100, y = 200, width = 50, height = 20

If you could somehow tell the object at 0x2001 to be equal to 0x1001, using your mergeRegions method, would Java try to do something like this?

  • 0x1001: x = 0, y = 5, width = 20, height = 30
  • 0x2001: 0x1001

This wouldn't work though, because the Java objects are both supposed to be Region objects, each with the same fields and methods. If we wipe out the the Java object at 0x2001, and just put in a plain address, none of the existing references to 0x2001 would work, because they're all expecting a Region object at that address. That's why you cannot "directly assign" one Java reference to another.

Here are three hints to help you redesign your algorithm:

  1. Instead of copying the address 0x1001 into 0x2001, you can copy all of the data from 0x1001 into the object at 0x2001. This would make both objects equivalent, but separate.
  2. You can introduce one level of indirection. If you know C, think "pointers to pointers". Your regions array would hold a references to IndirectRegion objects, which would in turn hold references to the actual Region objects. When you want to update region2 to region1, you only need to ask one of the IndirectRegion objects to update its internal reference.
  3. Wait until the end of your algorithm before you merge the regions. If you're able to collect up all the merge operations, you may be able to execute all of them in a single O(n) loop.


You cannot do this because it will break the contract of how that object might behave to other callers. Your first for-loop is the best you can do. A better solution might be to not use an array and instead use something that has O(1) access. For example, a Set<T>. You could something like

set.remove(region2);
set.add(region1);

Which will be really fast if you have written, .equals() and .hashcode()

Another solution is to copy everything from one class to another. I am not sure how I feel about this and if it is even safe. But you can do something like.

public void mergeRegions(Region region){
    this.a=region.a;
    this.b=region.b;
    this.c=region.c;
    this.d=region.d;
}


What are you using the array for? Amir's and Dan's suggestions about swapping the contents or using an indirection came to my mind, too. But I have the feeling that maybe you should change your data structure. So could you please elaborate on the usage of your array?

For instance, if you just have a few regions, n, then maybe instead of using an array of region-objects, you could use n sets of integers and use set operations like union, intersection and complement, or swapping sets. Or you don't even need the integers any more, but could use EnumSets or EnumMaps.

If you happen to have Josh Bloch's book "Effective Java", take a look at Item 25 about arrays and Item 32/33 about EnumSets/EnumMaps.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜