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?

+1


a source to share


4 answers


I would turn on the property change notification in the setName method of the element and process it in the container object that listens for this notification.



+1


a source


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 method rename

    that only changes its own name, and MyContainer

    has a method rename

    that calls MyElement.rename

    and moves an object on the map to a new key.
+1


a source


If the item is only used in this container.

Place the rename operation in a container.

Make the rename method private on the element so that another programmer can't accidentally change only the element and forget to update the container.

0


a source


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?

0


a source







All Articles