0

Here's my code:

class Main{
    static HashMap<Wrapper, Thing> map = new HashMap<Wrapper, Thing>();

    public static void main(String[] args){
        map.put(new Wrapper(1,2,3), new Thing(...));
        System.out.println(map.containsKey(new Wrapper(1, 2, 3)); // prints 'false'
    }

    private static class Wrapper{
        int[] array;
        public Wrapper(int... array){
            this.array = array;
        }
        public boolean equals(Object object){
            if(!(o instanceof Wrapper)) return false;
            return Arrays.equals(this.intervals, ((Wrapper) o).intervals);
        }
    }
}

Why does map.containsKey(new Wrapper(1, 2, 3) return false?

Aviv Cohn
  • 15,543
  • 25
  • 68
  • 131

1 Answers1

2

The hashCodes have to match and unless you override hashCode() it is randomly generated by default.

Try

public int hashCode() { return Arrays.hashCode(array); }
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • Thanks, I'll try this. BTW the reason I need a wrapper class is because it doesn't work with plain arrays as the map keys. I.e. `map.containsKey(new int[]{1,2,3})`, where an identical array exists as a key in the map, returns false. Is there a way for this to work without a wrapper that overrides `hashcode`? – Aviv Cohn Sep 14 '14 at 00:27
  • @Prog You can have a TreeMap with a custom comparator. – Peter Lawrey Sep 14 '14 at 00:33
  • (Unfortunately?) array.equals doesn't do what you think it would do and just checks pointer equality. See http://stackoverflow.com/questions/8777257/equals-vs-arrays-equals-in-java for more info. – nmore Sep 14 '14 at 00:34
  • I see. I'll stick with the wrapper. – Aviv Cohn Sep 14 '14 at 00:34
  • BTW out of curiousity: why do I have to override both `equals` and `hashcode`? Why does the map need both of them? – Aviv Cohn Sep 14 '14 at 00:36
  • 1
    When you tell a hash map to look for or get an element, it first calculates the hashcode of that object and checks if an object with the same hashcode is in the map. If it is, then I think it checks equality on the two objects (the one that it found and the one that you gave it) if there is more than one object with the same hashcode. I'm not 100% sure on the equality part, but it for sure checks the hashcode first. In your case it did not even find the object in the map with the same hashcode. – nmore Sep 14 '14 at 01:00