Java HashMap.get() returns null when I create a new instance of an object as a key

后端 未结 3 1917
Happy的楠姐
Happy的楠姐 2020-12-22 01:41

I\'m making a spreadsheet application and I\'m using a HashMap to store the data in the cells. As the key I\'m using a Point class, which only has the number of rows and col

相关标签:
3条回答
  • 2020-12-22 02:13

    By default, Point's equals method uses == i.e. object identity. Because Hashmap uses the equals method, it ends up comparing the key using == which would return false unless it's the same object.

    To fix this, Implement Point's equals and hashCode method so that point1.equals(point2) returns true if the coordinates are same.

    0 讨论(0)
  • 2020-12-22 02:17

    Since, you are using the Point as the key to the hashmap you would need to override the default equals and hashCode method

    Untested Code

    @Override
    public boolean equals(Object obj){
    
    if (obj == null) 
        return false;
    if (obj == this) 
        return true;
    if (!(obj instanceof Point.class))
        return false;
    Point point = (Point) obj;
    return this.x == point.x && this.y == point.y;
    }
    
    0 讨论(0)
  • 2020-12-22 02:21

    To detail my comment above, your Point class should implement hashcode and equals like following: (many implementations exist, it's just one that works) Supposing that your instance's variables are x and y.

        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
    
            Point point = (Point) o;
    
            if (x != point.x) return false;
            if (y != point.y) return false;
    
            return true;
        }
    
        public int hashCode() {
            int result = x;
            result = 31 * result + y;
            return result;
        }
    

    Otherwise, if you don't override those methods, Object's Javadoc explains well your issue:

    As much as is reasonably practical, the hashCode method defined by
         * class {@code Object} does return distinct integers for distinct
         * objects. (This is typically implemented by converting the internal
         * address of the object into an integer, but this implementation
         * technique is not required by the
         * Java<font size="-2"><sup>TM</sup></font> programming language.)
         *
         * @return  a hash code value for this object.
         * @see     java.lang.Object#equals(java.lang.Object)
         * @see     java.lang.System#identityHashCode
         */
        public native int hashCode();
    

    Thus, new Point(1,2) would not be considered as equal to new Point(1,2) and therefore, could never be retrieved from your Map.

    0 讨论(0)
提交回复
热议问题