3

I have a series of objects that contain a name field, and I want to store them in a HashMap, with the key of each object being it's name. Is there a way to do this such that changing the object's name field also changes the key in the HashMap (and even vice versa).

(is it possible to have a sort of double reference in Java, such that the key references the name field (which references the String)).

0

5 Answers 5

4

This isn't supported with any native functionality.

What you would have to do is have a special method somewhere like

public static void updateName(String oldname, String newname, Map<String,MyObject> map) {
    synchronized(map) {
        MyObject obj = map.remove(oldname);
        obj.setName(newname);
        map.put(newname,obj);
    }
}

And document everything properly so developers know to be very careful when changing the name.

Note that this doesn't do the typical error checking (what if it doesn't exist in the old map? what if something is null?) - those sad path cases are left unhandled here. I'm sure they aren't beyond the grasp of a typical programmer. =)

Sign up to request clarification or add additional context in comments.

Comments

0

You could do this by adding another object that assigned java.util.UUID to the name and use the UUID as the key in your HashMap. However, you would need another map to manage the UUID to Name mappings. If your class is more involved that just a name this may be the best solution. Otherwise, just remove the old Name from the HashMap and insert a new name. You could implement this in a setName() method and make your name a private property to insure it is not updated directly.

Comments

0

The standard HashMap won't move values between buckets once the value has been inserted. It would be too easy to unexpectedly lose values, if the key change meant that an existing value is now overwritten by the moved value.

You have to do something like corsiKa's solution, though I'd throw an exception before map.remove() if map.get(newname) != null (since otherwise you might unexpectedly lose the existing value at key newname).

1 Comment

There's other special case checking that can be done, like null checks, what if old name and new name are the same, etc.
0

Assuming your "Nameable" objects are only ever accessed through the map you can do something like this.

  1. Create a class that implements Map.
  2. When you return an object from the map, actually return a decorated version (using cglib or something like that), that overrides the setName() method. When setName is called, change the name, but also have the code implementing the decorator update the map with the new key as corsiKa described.

Comments

0

I wonder what is your use case. If you don't change this names often, and/or don't have many objects with name, but you need to find by key often, you could create your own implementation of Map (inheriting from HashMap). There you could store everything as usually, and when get is called, try to do super.get, if it returns null, check all the objects in map, if found, update the map and return the object. So the algorithm looks like this:

  1. Try standard implementation get
  2. If not found, check all super.values() for desired name
  3. If found, put(name, foundObject) and return foundObject

Be careful however, as this might break something if you sometimes assign a name to an object, which was in the past assigned to another object. In such case you could return old object from the map.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.