Java存储HashMap中的对象,由elements字段键入

时间:2014-02-03 19:45:16

标签: java hashmap

我有一系列包含name字段的对象,我想将它们存储在HashMap中,每个对象的键都是name。有没有办法做到这一点,以便更改对象的name字段也会更改HashMap中的键(反之亦然)。

(是否可以在Java中使用一种双引用,以便键引用name字段(引用String)。)

5 个答案:

答案 0 :(得分:4)

任何本机功能都不支持此功能。

您需要做的是在

之类的地方使用特殊方法
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);
    }
}

并妥善记录所有内容,以便开发人员在更改名称时非常小心。

请注意,这不会执行典型的错误检查(如果旧映射中不存在该怎么办?如果某些内容为null,该怎么办?) - 这些悲伤的路径案例在此处未处理。我相信他们并不是一个典型程序员的掌握。 =)

答案 1 :(得分:0)

您可以通过添加另一个将java.util.UUID分配给名称的对象并使用UUID作为HashMap中的键来完成此操作。但是,您需要另一个映射来管理UUID到Name映射。如果你的班级更多涉及只是一个名字,这可能是最好的解决方案。否则,只需从HashMap中删除旧名称并插入新名称。您可以在setName()方法中实现此功能,并将您的名称设为私有属性,以确保它不会直接更新。

答案 2 :(得分:0)

插入值后,标准HashMap不会在存储桶之间移动值。如果密钥更改意味着现有值现在被移动的值覆盖,则意外丢失值将太容易。

你必须做一些类似corsiKa的解决方案,虽然我会在map.remove()之前抛出一个异常,如果map.get(newname)!= null(因为否则你可能会意外地丢失关键newname的现有值)。

答案 3 :(得分:0)

假设您的“可命名”对象只能通过地图访问,您可以执行以下操作。

  1. 创建一个实现Map的类。
  2. 当您从地图返回一个对象时,实际上会返回一个装饰版本(使用cglib或类似的东西),它会覆盖setName()方法。当调用setName时,更改名称,但也让实现装饰器的代码使用新密钥更新地图,如corsiKa所述。

答案 4 :(得分:0)

我想知道你的用例是什么。如果您不经常更改此名称,和/或没有多个具有名称的对象,但您需要经常按键查找,则可以创建自己的Map实现(继承自HashMap)。你可以在那里存储所有内容,当调用get时,尝试执行super.get,如果它返回null,检查map中的所有对象,如果找到,则更新地图并返回对象。所以算法看起来像这样:

  1. 尝试标准实施get
  2. 如果找不到,请检查所有super.values()是否有所需名称
  3. 如果找到,put(name, foundObject)并返回foundObject
  4. 但是要小心,因为如果有时为某个对象指定一个名称(过去分配给另一个对象),这可能会破坏某些内容。在这种情况下,您可以从地图返回旧对象。