-1

I defined a class Point that represents a point on an integer lattice. I have overridden methods for hashCode() and equals(Object).

HashMap does not seem to do anything when using HashMap.put(Point, Double) for Points with a coordinate value >= 128. No error is thrown, but attempting to access Points from the HashMap will result in the key not being found. I am well under INTEGER.MAX_VALUE, and have plenty of memory available.

Here is my Point class:

import java.util.ArrayList;

public class Point {
    protected int dimension;
    protected ArrayList<Integer> coordinates;

    public Point(int[] coordinates){
        this.coordinates = convertArray(coordinates);
        dimension = coordinates.length;
    }

    private ArrayList<Integer> convertArray(int[] array){
        ArrayList<Integer> newArray = new ArrayList<Integer>();
        for(int i = 0; i < array.length; i++){
            newArray.add(array[i]);
        }
        return newArray;
    }

    @Override
    public int hashCode(){
        // Some arbitrary quick hash
        return coordinates.get(0);
    }

    @Override
    public boolean equals(Object o){
        Point p = (Point)o;
        if(dimension != p.coordinates.size())
            return false;
        for(int i = 0; i < p.coordinates.size(); i++){
            if(coordinates.get(i) != p.coordinates.get(i)){
                return false;
            }
        }
        return true;
    }
}

and the test I ran:

import java.util.*;
public class random {

    public static void main(String[] args) {
        HashMap<Point, Double> weight = new HashMap<Point, Double>((int)(150 * 150 * .75 + 1));
        for(int i = 0; i < 150; i++){
            for(int j = 0; j < 150; j++){
                int [] tmpArray = {i, j};
                weight.put(new Point(tmpArray), Math.random());
            }
        }

        for(int i = 0; i < 150; i++){
            for(int j = 0; j < 150; j++){
                int [] tmpArray = {i, j};
                if(weight.get(new Point(tmpArray)) == null){
                    System.out.println("[" + i + ", " + j + "]: ");
                    System.out.println(weight.containsKey(new Point(tmpArray)));
                }
            }
        }
    }
}

Any ideas would be helpful. Thanks!

Bryant
  • 38
  • 4

1 Answers1

0
@Override
    public boolean equals(Object o){
        Point p = (Point)o;
        if(dimension != p.coordinates.size())
            return false;
        for(int i = 0; i < p.coordinates.size(); i++){
            if(coordinates.get(i) != p.coordinates.get(i)){
                return false;
            }
        }
        return true;
    }

Your equals() implementation is bad when you compare objects you must use equals to observational equality instead of == that is if they point to same location (!=).

Integer is an object so you have to use equals .Sometimes doing == works fine to same values cause they are cached ( -128 to 127).

Example:

Integer a = 1000, b = 1000;  
System.out.println(a == b); // false  
Integer c = 100, d = 100;  
System.out.println(c == d); // true
Integer e=5 , f= new Integer(5);
System.out.println(e == f) // false

Instead of looping your list you can simply use provided list method equals()

Returns true if and only if the specified object is also a list, both lists have the same size, and all corresponding pairs of elements in the two lists are equal

Also you shouldn't use as Key in hash valued map mutable objects. Are mutable hashmap key dangerous?

If an object’s hashCode() value can change based on its state, then we must be careful when using such objects as keys in hash-based collections to ensure that we don’t allow their state to change when they are being used as hash keys. All hash-based collections assume that an object’s hash value does not change while it is in use as a key in the collection. If a key’s hash code were to change while it was in a collection, some unpredictable and confusing consequences could follow.

Community
  • 1
  • 1
nachokk
  • 14,363
  • 4
  • 24
  • 53