1

I'm trying to get a value with the key. I'm using get() method. My key is an object composed with int and String. So I make and object

HashMap<Keys,String> test = readFile(fileName2);
Keys myKey = new Keys(2,"SM");
test.get(myKey);

And I received null. When I look at debbuging mode or when I print keySet I received something like this

[Keys@d9c6e2, Keys@10285d8, Keys@c3dd7e]

although my key should be

[1,"GM", 2,"SM", 3"PM"]

why the key look like this Keys@d9c6e2 instead of 2,"SM"? and how to get the value with the key 2,"SM"?

I override toString methid in Keys . It looks better but still i have null value and im sure there is some value.

    Keys myKey = new Keys(2,"GL-G--T");
    System.out.println(myKey.toString());
    System.out.println(test.get(myKey.toString()));
    Set keyset = test.keySet();
    System.out.println(keyset);


    2,GL-G--T
    null
    [3,PNSN--G, 2,GL-G--T, 1,SM]
Ewa Kania
  • 41
  • 1
  • 2
  • 8
  • Do you have a toString method on your keys? Looks like the java object reference is being shown – Kevin L Jul 01 '14 at 17:20

3 Answers3

4

You need to override toString method on your Keys object. Otherwise you will get the default toString provided by java.lang.Object.

You could implement the toString method to look something like this:

public class Keys {
    private final Integer i;
    private final String s;

    public Keys(Integer i, String s) {
        this.i = i;
        this.s = s;
    }

    @Override 
    public String toString() {
        return i + "," + s;
    }
}

if you want the quotes to be displayed then you'd need to provide those:

return i + ",\"" + s + "\"";

You'll also need to override the equals and hashCode for this object to be used as a key in a map:

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof Keys)) {
            return false;
        }
        Keys other = (Keys)o;
        return other.s.equals(s) && other.i.equals(i);
    }

    @Override
    public int hashCode() {
        return toString().hashCode();
    }

If you don't override equals and hashcode, then the map uses the default implementations, which results in two Keys objects with the same values being unequal.

Community
  • 1
  • 1
Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
  • To be honest, though, this all ends up being overengineered for no tangible benefit. If the hashCode() method is simply concatenating the key elements into a string and then calling hashCode on that, I'd just do away with the special Keys object altogether and just use a concatenated string as the key to the hash map! – Neil Coffey Jul 01 '14 at 17:51
  • @Neil: I agree this particular example is overengineered. but this does show the OP how to get this object working with a map. – Nathan Hughes Jul 01 '14 at 17:51
  • Sorry, yes I do agree-- it's a good answer per se. I think it's just worth mentioning that in the end there's a more straightforward solution to the overall problem! – Neil Coffey Jul 01 '14 at 18:02
  • I edit my class keys and i still have a problem with null value althogh i know there is a value - I see it in debug mode. – Ewa Kania Jul 02 '14 at 08:34
  • @Ewa: then add your toString method implementation to the question. without that there's nothing to say except your toString method is evidently broken. – Nathan Hughes Jul 03 '14 at 14:16
1

You could as you are doing use a special Keys object as the key to your hash map-- you then just need to correctly implement hashCode and equals on that Keys class as others have explained.

Unless you have a specific reason not to, though, you really could just use a String as the key to the hash map. Create some method such as the following:

private static String getHashMapKeyFor(int intKey, String stringKey) {
  return stringKey + "|" + intKey;
}

and declare your hash map as taking a String as the key type. Then, whenever you want to put/find a value in the hash map, call the above method first to get the actual key to use to the hash map.

Using the custom object class may have a superficial air of "correctness" or "engineeredness" to it, but in reality, just using a String will generally perform equally well and if anything may even save slightly on memory.

Neil Coffey
  • 21,615
  • 7
  • 62
  • 83
0

In your Keys.java object override the toString method. Currently it's using the method defined in java.lang.Object#toString

user3465651
  • 706
  • 1
  • 4
  • 22