简体   繁体   中英

Hashtable get() operation not working as per documentation

According to the official documentation for the Java Hashtable class ( https://docs.oracle.com/javase/7/docs/api/java/util/Hashtable.html ), the get() opperation will return one of it's recorded values, if said value has a key that returns true when the parameter is fed into that key's equals() opperation.

So, in theory, the following code should return "Hello!" for both of the Hashtable's get() queries:

public static class Coordinates implements Serializable {

    private int ex;
    private int why;

    public Coordinates(int xCo, int yCo) {
        ex = xCo;
        why = yCo;
    }

    public final int x() {
        return ex;
    }

    public final int y() {
        return why;
    }

    public boolean equals(Object o) {
        if(o == null) {
            return false;
        } else if(o instanceof Coordinates) {
            Coordinates c = (Coordinates) o;
            return this.x() == c.x() && this.y() == c.y();
        } else {
            return false;
        }
    }
}

Hashtable<Coordinates, String> testTable = new Hashtable<Coordinates, String>();
Coordinates testKey = new Coordinates(3, 1);
testTable.put(testKey, "Hello!");
testTable.get(testKey); //This will return the "Hello" String as expected.
testTable.get(new Coordinates(3, 1)); //This will only return a null value.

However, get() doesn't work as it's supposed to. It seems to only work if you litterally feed it the exact same object as whatever was the original key.

Is there any way to correct this and get the Hashtable to function the way it's described in the documentation? Do I need to make any adjustments to the custom equals() opperation in the Coordinates class?

To be able to store and retrieve objects from hash-based collections you should implement/oeverride the equals() as well as hashCode() methods of the Object class. In your case, you have overridden the equals() and left the hashCode() method to its default implementation inherited from the Object .

Here is the general contract of the hashCode() method you must consider while implementing it:

  • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.

  • If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.

  • It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.

And here is an example implementation that is generated from my IDE (as alread mentioned by @Peter in the comment area) which you can modify to suit your requirements:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM