如何修改地图元素键

时间:2009-05-13 11:09:42

标签: language-agnostic map

我有一个容纳元素图的容器。

class MyContainer{
.....
Map<String,MyElement> elements = new ...
...
}

每个元素都有name属性。地图中的关键是元素的名称。即方法插入如下:

void addElement(MyElement elem){
    elements.put(elem.getName,elem);
 } 

我需要使用地图数据结构,因为我有许多基于元素名称的读取操作。

问题是我需要支持修改元素的名称。更改元素名称必须导出地图中的更改。 (使用新密钥插入元素,否则我将无法找到该元素)

我考虑过两个选择:

  1. 将setName方法添加到MyElement类,该类将更新其名称已更改的容器。

  2. 不要将setName方法添加到MyElement类,将重命名元素方法添加到容器中,容器将负责更新地图中的元素名称和键。

  3. 选项1意味着我必须保持从每个元素到容器的引用。 (程序的这一部分应保持较低的内存占用)。

    你怎么说?你看到更好的选择吗?

4 个答案:

答案 0 :(得分:1)

我会在元素的setName方法上触发属性更改通知,并在侦听该通知的容器对象中处理它。

答案 1 :(得分:1)

首先请注意,如果MyElement可以设想在没有MyContainer的情境中使用,那么选项1就可以了。

MyContainerMyElement有明显的关系,因为它的代码通过其地图引用了MyElement个实例。反之则不然:MyElement中的代码不需要引用MyContainer。所以选项2更好。

但也许你可以选择第三种混合选择:

  • MyElementrename方法,只更改自己的名称,MyContainerrename方法调用MyElement.rename并移动对象映射到新密钥。

答案 2 :(得分:0)

如果元素仅用于此容器中。

将重命名操作放在容器上。

将元素上的重命名方法设为私有,这样另一个程序员就不会意外更改元素而忘记更新容器。

答案 3 :(得分:0)

选项2是最简单和最有效的,因此我的选择。 显然你知道,那么什么是dillema?

另一种选择是创建一个MyString类,它既可以作为std :: string,也可以作为对MyContainer的引用。 MyString的修改方法将负责重新编写,并且你的占用空间仍然很小。 E.g:

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 */

请注意,此选项也支持多个键和容器,例如FirstName,LastName(如果只有这些是唯一的......)

另一个选择是MyContainer是单身。

需要考虑的另一件事是,名称有多久会改变?