我有一系列包含name
字段的对象,我想将它们存储在HashMap中,每个对象的键都是name
。有没有办法做到这一点,以便更改对象的name
字段也会更改HashMap中的键(反之亦然)。
(是否可以在Java中使用一种双引用,以便键引用name
字段(引用String)。)
答案 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)
假设您的“可命名”对象只能通过地图访问,您可以执行以下操作。
答案 4 :(得分:0)
我想知道你的用例是什么。如果您不经常更改此名称,和/或没有多个具有名称的对象,但您需要经常按键查找,则可以创建自己的Map实现(继承自HashMap)。你可以在那里存储所有内容,当调用get
时,尝试执行super.get
,如果它返回null,检查map中的所有对象,如果找到,则更新地图并返回对象。所以算法看起来像这样:
get
super.values()
是否有所需名称put(name, foundObject)
并返回foundObject 但是要小心,因为如果有时为某个对象指定一个名称(过去分配给另一个对象),这可能会破坏某些内容。在这种情况下,您可以从地图返回旧对象。