Hashtable get()操作无法按文档

时间:2016-05-17 10:16:20

标签: java hashtable equals

根据Java Hashtable类(https://docs.oracle.com/javase/7/docs/api/java/util/Hashtable.html)的官方文档,get()opperation将返回其中一个记录值,如果所述值有一个键,当参数返回true时被输入到该键的equals()操作中。

因此,理论上,以下代码应返回" Hello!"对于两个Hashtable的get()查询:

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.

然而,get()并没有像它应该的那样工作。它似乎只有在你通过它提供与原始密钥完全相同的对象时才能工作。

有没有办法纠正这个问题并使Hashtable按照文档中描述的方式运行?我是否需要对Coordinates类中的自定义equals()操作进行任何调整?

1 个答案:

答案 0 :(得分:2)

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;
}