Skip to content
Advertisement

Java Map for unique object instances?

A library I use contains a certain object type, LackingObject (some type), which lacks an attribute of type Ext (some type). If I was able to change the LackingObject class, I would simply add an attribute with type Ext, but LackingObject cannot be changed, nor extended. What I’d do now in languages like C or C++ is to create a Map that maps LackingObjects to Exts, which, in Java, would (somewhat equivalently) look like

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

so whenever I encounter a LackingObject in my code for the first time, I can call

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

and then, to recall that added attribute, I would call

Ext resolved = object_extension.get(o);

This however will not work, as the default HashMap behavior is to map the results of Object::hashCode, not Objects, to values, so if I had two (apart from the Ext value) equal LackingObjects, they could not both be a unique key in a java.util.HashMap.

The question: In Java, is there at least one of the following:

  • a way to let the standard libraries map object instances to values?

  • a way to receive an unique identifier for an object instance?

I found a 7 year old post somewhat related to this topic, but I hope things have changed during the years.

The final resort would be to create a wrapper class,

class Wrapper{
    LackingObject o;
    Ext v;
}

but that overall seems to me like an inferior solution, as we would be adding a potentially redundant new object type to the project structure, instead of just adding a few statements.

(Unrelated to the topic, as this part of the problem is specific to my current condition, but this ‘inferior solution’ would also require me to change a lot of already existing source code, which I would happily avoid, if possible.)

Advertisement

Answer

You can use IdentityHashMap for this purpose. According to its documentation:

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.
Advertisement