22

So, I'd like to use a java map where the keys are an object...but rather than keying on the object's value, they key on the object ID. So, something like the following would be totally valid code:

Map<String, Integer> map = new HashMap<String, Integer>();

String s1 = "hi!";
String s2 = "hi!";

map.put(s1, 10);
map.put(s2, 47);

Is this possible? Is there a simple way to do this without building an object ID or something overly cumbersome in my class? Basically, I need a way to associate an ever-changing list of values with a given object. This list of values will potentially be different for objects that have the same value, hence why the default map doesn't work. Other than refactoring my class to do this myself (not really an option, given the time) is there anything that I could use?

Thanks.

EDIT: Further information.

The example above was just an example. What I will be using this for is the implementation of a Uniform-Cost search algorithm. For any given node in a search with this algorithm, one must also have the path that has been taken so far. The reason a value-based hash map doesn't work is that this algorithm can reiterate over already-explored nodes. The paths would be different at this point, although the value of "where am I now?" is identical.

4
  • 1
    If you don't implement equals() and hashCode() by yourself, you're basically inheriting Objects implementation, which compare by identity, not equality. Commented Apr 26, 2011 at 22:54
  • @Helper: I think (not sure) that String redefines equals() and hashCode() so that it compares by equality. Otherwise none of my string based maps would work :( Commented Apr 26, 2011 at 22:56
  • @Giacomo: String absolutely overrides equals() and hashCode(). Commented Apr 26, 2011 at 22:57
  • Correct, but he says in my class. As far as I understand, the Strings were only given as examples. Commented Apr 27, 2011 at 7:45

5 Answers 5

29

I think IdentityHashMap will do the trick. However, both strings will point to the very same instance since you used a string literal. Try s1 = new String("hi!") and s2 = new String("hi!") together with an IdentityHashMap instead.

Sign up to request clarification or add additional context in comments.

1 Comment

Didn't think about it. +1 But maybe the asker is searching for a multi-map and he doesn't formalize it the correct way. I find that design (s1 and s2 substantially equal but pointing to different values) not good.
7

You should have a look at IdentityHashMap.

This class implements the Map interface with a hash table, using reference-equality in place of object-equality when comparing keys (and values).

1 Comment

This is exactly the right answer. As it does not require an additional dependency like Guava
2

Check out Guava's Multimaps (implementations listed on the Multimap interface page).

3 Comments

This is probably a sensible approach. I don't see the point of keeping a reference to two distinct but equal strings and then lookup the values using both of ones. I bet that it's just poor design, and has to be corrected using a MultiMap
I should have been more clear in my example, but the object in question is not a String. While it is possible that the design could be better, I am DEFINITELY wanting to associate differing values with specific objects which can be semantically identical.
So if the Object is not a String, and does not override equals() and hashCode(), then equals() and hashCode() work by checking identity. So you don't need anything else than a standard Map. Do you override equals() and hashCode() ? If the answer is 'yes' you're 100% right.
0

You are searching for a multi-map. Java Collection Framework doesn't give you this. But you can mimic it associating a LinkedList (eventually with a single element) to every key. It's very easy.

Comments

0

Just for completness: Guava's MapMaker makes maps with identity equivalence as a default for weak and soft keys. Look at code here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.