1

我有一个包含元素映射的容器。

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

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

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

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

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

我想过两个选择:

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

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

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

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

4

4 回答 4

1

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

于 2009-05-13T11:32:46.507 回答
1

首先,请注意,如果MyElement可以想象可以在没有 的上下文中使用MyContainer,则选项 1 不适用。

MyContainer与 有明显的关系MyElement,因为它的代码MyElement通过它的映射引用实例。反之则不然:中的代码MyElement不需要引用MyContainer. 所以选项2更好。

不过,也许您可​​以选择第三种混合选项:

  • MyElement有一个rename只更改自己名称的方法,并且MyContainer有一个rename调用MyElement.rename映射中的对象并将其移动到新键的方法。
于 2009-05-13T11:35:00.340 回答
0

If the element is only used in this container.

Put the rename operation on the container.

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

于 2009-05-13T11:44:48.357 回答
0

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

另一种选择是创建一个 MyString 类,它将作为 std::string 和对 MyContainer 的引用。MyString 的修改方法将负责重新映射,并且您的占用空间仍然很小。例如:

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 是单例。

要考虑的另一件事是,名称多久更改一次?

于 2009-05-13T11:55:16.920 回答