Java 唯一对象实例的映射?

Java Map for unique object instances?

我使用的库包含特定对象类型 LackingObject(某种类型),它缺少类型 Ext(某种类型)的属性。如果我能够更改 LackingObject class,我会简单地添加一个类型为 Ext 的属性,但是 LackingObject 不能更改,也不能扩展。我现在用 CC++ 之类的语言做的是创建一个 MapLackingObjects 映射到 Exts,在 Java, 会(有点等价地)看起来像

Map<LackingObject, Ext> object_extension = new HashMap<>();

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

LackingObject o = ...;
Ext value = compute_value_for(o, ...);
object_extension.put(o, value);

然后,为了回忆那个添加的属性,我会调用

Ext resolved = object_extension.get(o);

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

中的唯一键

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

我发现一个 7 岁的 post 与这个话题有些相关,但我希望这些年来事情有所改变。

最后的办法是创建一个包装器 class,

class Wrapper{
    LackingObject o;
    Ext v;
}

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

(与主题无关,因为这部分问题是针对我目前的情况,但是这个'inferior solution'也需要我更改很多已经存在的源代码,我很乐意避免,如果可能的话。)

您可以使用 IdentityHashMap 来达到这个目的。根据其文档:

This class implements the Map interface with a hash table, using reference-equality in place of object-equality when comparing keys (and values). In other words, in an IdentityHashMap, two keys k1 and k2 are considered equal if and only if (k1==k2). (In normal Map implementations (like HashMap) two keys k1 and k2 are considered equal if and only if (k1==null ? k2==null : k1.equals(k2)).)
This class is not a general-purpose Map implementation! While this class implements the Map interface, it intentionally violates Map's general contract, which mandates the use of the equals method when comparing objects. This class is designed for use only in the rare cases wherein reference-equality semantics are required.

System.identityHashCode

the guts of IdentityHashMap (obtained thanks to ) 中挖掘,我找到了部分问题的答案:

What is the way to receive a unique identifier for an object instance?

…关键是:System.identityHashCode

签名为

int identityHashCode(Object);

引用 Javadoc:

Returns the same hash code for the given object as would be returned by the default method hashCode(), whether or not the given object's class overrides hashCode(). The hash code for the null reference is zero.