tags:

views:

74

answers:

5

I have the following TreeMap:

TreeMap<String, Integer> distances = new TreeMap<String, Integer>();

and it contains both strings, "Face" and "Foo", with appropriate values, such that:

System.out.println(distances); 

Yields:

{Face=12, Foo=2}

However, distances.get(Face) returns null, even though distances.get(Foo) properly returns 2. Previously, distances.get(Face) worked, but for some reason, it stopped working. Note I print out the map right before calling get() for both keys, so I haven't accidentally changed Face's value to null. Has anyone else ever encountered this problem? Is there anything I can do? I'm having a terrible time simply trying to figure out how to debug this problem.

NOTE: In the real code I'm not actually using Strings, but a different object, so it's: TreeMap<Object, Integer>. So it's not simply a confusion of variable names vs. literal strings.

SECOND NOTE: I also feel pretty confident about my implementations of hashcode() and equals() for the object I'm using. (Also, if my implementations weren't correct, wouldn't it not work from the beginning? Instead of stopping to work randomly?)

A: 

Are you sure that the values "Foo" and "Face" are both Strings?

This code works for me:

        TreeMap<String, Integer> map = new TreeMap<String, Integer>();
        map.put("a", 1);
        map.put("b", 2);

        System.out.println(map);
        System.out.println(map.get("a"));
        System.out.println(map.get("b"));

Will output {a=1, b=2} 1 2.

In your case, if Foo and Face are not both Strings, the map can not use them as keys for a lookup. Maybe you are using get(Face) where you should use get("Face")?

Lars Andren
See comment on other answer, but basically, I'm not actually using Strings, I'm using a different data type. Strings were for illustrative purposes.
smessing
A: 

Are you confusing the string literal "Face" with a variable called Face? If you're literally using distances.get(Face), that means you're trying to pass in a variable Face, and it's not surprising that you're getting null back out (unless that's a String variable whose contents you've previously added to the map).

Instead try distances.get("Face"). If that works, it means "Face" is the string you're using as a key -- which isn't the same as a variable Face that might contain a string.

Etaoin
Sorry, this needs clarification: in my actual code I'm using different objects (my own data type), so the confusion you speak of can't be what's happening.
smessing
A: 

@smessing did you properly implement equals and hashcode methods on your class that objects Foo and Face belong to? When you want to store an object in a List, Map or a Set then it is a requirement that equals and hashCode are implemented so they obey the standard contract as specified in the documentation. If these are not properly done, a get operation can result in unexpected results as you mentioned.

ring bearer
I have implemented both, and feel fairly confident that they aren't the problem. Also, remember that for a while the get() calls return the proper values, but at some point stop...
smessing
-1 - hashCode is irrelevant for a TreeMap!
Stephen C
+3  A: 

In response to your note: everyone is asking if you've overridden equals() and hashcode() properly -- which is important, yes. But this is a TreeMap, which means you also have to care about comparisons -- whether you're using Comparable objects or an external Comparator, you need to make sure that your comparisons are consistent (are your objects mutable?) and that they're consistent with your equals() method.

Incidentally, when you said in your original question that you were using String objects, you did yourself a disservice -- Strings are immutable and their comparison methods aren't under consideration here, so the question was fundamentally different; now that we know your own code is involved, the field of possible solutions is wider.

Etaoin
I see your point about the mention of `String` objects, sorry about that.As for your comment, I'm not sure I follow. What do you mean "make sure your comparisons are consistent"... make sure that my objects aren't changing without me be aware of it? If that's the case, I also feel fairly confident that the objects themselves are not changing in any way. The code this is all in is for sorting amongst the objects, but not for operating *on* them, if that makes sense.
smessing
A: 

If you are assigning Face with some other reference object/variable, check if that is becoming null.

If your face object is pointing to the reference of another object and the other object sets it to null, Face also becomes null.

Vaishak Suresh