How to change the key of a map item
I have a container that contains a map of items.
class MyContainer{
.....
Map<String,MyElement> elements = new ...
...
}
Each element has a name property. The key on the map is the name of the item. that is, the method insertion looks like this:
void addElement(MyElement elem){
elements.put(elem.getName,elem);
}
I need to use a map data structure because I have a lot of reads based on the item name.
The problem is I need to support modifying the element name. Changing the name of an element should cause changes to the map. (insert an item with a new key, otherwise I can't find this item)
I thought of two options:
-
add a setName method to the MyElement class, which will update the container so that its name is changed.
-
do not add the setName method to the MyElement class, add the rename method to the container, the container will be responsible for updating the element name and key on the map.
Option 1 means I have to maintain a link from each element to the container. (this part of the program should keep memory low).
What do you say? do you see the best option?
a source to share
First of all, note that if MyElement
it can presumably be used in context without MyContainer
, then option 1 is missing.
MyContainer
has an obvious relationship with MyElement
, since its code refers to instances MyElement
through its map. The converse is not true: code MyElement
should not reference MyContainer
. So option 2 is better.
Perhaps, however, you could go for the third hybrid option:
-
MyElement
has a methodrename
that only changes its own name, andMyContainer
has a methodrename
that callsMyElement.rename
and moves an object on the map to a new key.
a source to share
Option 2 is the simplest and most effective, so my choice. It is clear that you know this, so what about dillema?
Another option is to create a class MyString that will serve as both a std :: string and a reference to MyContainer. The modification methods of MyString will be responsible for remapping and you will still have a low footprint. For instance:.
class MyString;
class MyElement {
...
MyString name;
...
};
MyContainer * aContainer = new MyContainer;
new MyElement(MyString("Yaron Cohen",aContainer), ...); /* MyString need to be explicit only upon MyElement construction. takes care of inserting into container. */
...
MyElement * someElement = aContainer["Yaron Cohen"]; /* just std::string for lookup */
someElement->name = "Dana International": /* MyString takes care of remapping */
Note that this option also locks multiple keys and containers, for example. FirstName, LastName (if only they were unique ...)
Another option is that MyContainer is single.
Another thing to consider is how often the name changes?