0

Suppose, I have a HashMap:

HashMap<MyKey, Integer> HM = new HashMap<MyKey, Integer>();

MyKey corresponds to a data object with two integer elements (and a constructor for passing two integers).

HM.put(new MyKey(1,1234), 1); // this seems to work...

but, I cannot seem to use it:

System.out.println(HM.containsKey(new MyKey(1,1234)));

I get false.

Can a HashMap have a custom data object for a Key? What am I missing? Thanks...

n as
  • 609
  • 3
  • 7
  • 12

2 Answers2

1

You should override the equals() and hashcode() method in your MyKey class (or any other custom class for that matter that would go into a HashMap or Set). That way, when you say containsKey() (or the Set methodcontains(), or equals()), you would have explicitly specified what properties of MyKey to check for containment or equality.

You could have a simple equals() and hashCode() method like this in your MyKey class

@Override
public boolean equals(Object o) {
    boolean result = false;
    if (o instanceof MyKey) {
        MyKey mykey = (MyKey) o;
        result = (this.getX() == mykey.getX() && mykey.getY() == mykey.getY());
    }
    return result;
}

@Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + X;
        result = prime * result + Y;
        return result;
    }

(Assuming the fields in your MyKey class are X and Y)

Shobit
  • 776
  • 1
  • 6
  • 20
  • If I try: System.out.println(HM.containsKey(MyKey(1,1234))); – n as May 04 '13 at 22:38
  • I then get "cannot find symbol" (referring to MyKeys). Linguistically, I find it quite odd that I can put the item in, but then I actually have to have the originally specified item, not a copy of it. In any case, thanks for the help. I am iterating the HashList to find the actual item. – n as May 04 '13 at 22:44
  • @n as I have edited my answer. When overriding equals, hashCode should also be overriden. Also, see this: http://stackoverflow.com/questions/27581/overriding-equals-and-hashcode-in-java Hope that helps. – Shobit May 04 '13 at 23:21
0

In your System.out, you're generating a new MyKey(). You want to check if your hashmap contains a MyKey(1,1234), not a new MyKey(1,1234).

NWard
  • 2,016
  • 2
  • 20
  • 24
  • but if it compiles, it means `containsKey` do require a pointer, doesn't it? – Elazar May 03 '13 at 15:16
  • Not necessarily - it depends on the specific implementation of hashmap that the OP is using. It could just as happily compile with the new statement (and never return true) as it could with a reference to an existing object. – NWard May 03 '13 at 15:19