用于唯一对象实例的 Java Map?

Cap*_*jan 2 java reference hashmap instance

我使用的库包含某种对象类型LackingObject(某种类型),它缺少类型Ext(某种类型)的属性。如果我能够更改LackingObject类,我只需添加一个 type 属性Ext,但LackingObject不能更改,也不能扩展。我现在在语言中所做的C或者C++是创建一个Map映射LackingObjects到 的语言Exts,在 Java 中,它会(有点等效)看起来

Map<LackingObject, Ext> object_extension = new HashMap<>();
Run Code Online (Sandbox Code Playgroud)

所以每当我LackingObject第一次在我的代码中遇到 a时,我可以调用

LackingObject o = ...;
Ext value = compute_value_for(o, ...);
object_extension.put(o, value);
Run Code Online (Sandbox Code Playgroud)

然后,为了回忆那个添加的属性,我会打电话

Ext resolved = object_extension.get(o);
Run Code Online (Sandbox Code Playgroud)

然而,这不起作用,因为默认HashMap行为是将Object::hashCode, not的结果映射Objects到值,所以如果我有两个(除了Ext值)equal LackingObjects,它们不能都是java.util.HashMap.

问题:在 Java 中,是否至少存在以下一项:

  • 一种让标准库将对象实例映射到值的方法?

  • 一种接收对象实例的唯一标识符的方法?

我发现一个 7 年前的帖子与这个主题有些相关,但我希望这些年来情况有所改变。

最后的方法是创建一个包装类,

class Wrapper{
    LackingObject o;
    Ext v;
}
Run Code Online (Sandbox Code Playgroud)

但这在我看来总体上是一个劣质的解决方案,因为我们将向项目结构中添加一个潜在冗余的新对象类型,而不是仅仅添加一些语句。

(与该主题无关,因为这部分问题特定于我当前的情况,但是这种“劣质解决方案”还需要我更改许多现有的源代码,如果可能的话,我很乐意避免这样做。)

hev*_*ev1 7

您可以IdentityHashMap为此目的使用。根据其文档:

此类使用哈希表实现 Map 接口,在比较键(和值)时使用引用相等代替对象相等。换句话说,在 IdentityHashMap 中,两个键 k1 和 k2 被认为是相等的当且仅当 (k1==k2)。(在普通 Map 实现(如 HashMap)中,当且仅当 (k1==null ? k2==null : k1.equals(k2)) 两个键 k1 和 k2 被认为相等。)
此类不是通用 Map执行!虽然这个类实现了 Map 接口,但它故意违反了 Map 的一般约定,即在比较对象时强制使用 equals 方法。此类设计用于仅在需要引用相等语义的极少数情况下使用。