Java如果hashCode相同且equals为真,HashMap如何识别key对象?

Java how does HashMap identify the key object if hashCode are the same and equals is true?

我一直以为HashMap是通过hasCode和equals来识别key的。但是这段代码仍然没有给我返回值。我错过了什么?

import java.util.HashMap;
import java.util.Map;

/**
 * Created by kic on 25.04.15.
 */
public class TypePair {
    private final Class a;
    private final Class b;

    public TypePair(Class a, Class b) {
        this.a = a;
        this.b = b;
    }

    public TypePair(Object a, Object b) {
        this.a = a.getClass();
        this.b = b.getClass();
    }

    public boolean isPair (Object a, Object b) {
        return this.a.isAssignableFrom(a.getClass()) && this.b.isAssignableFrom(b.getClass());
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof TypePair) {
            return a.isAssignableFrom(((TypePair) obj).a) && b.isAssignableFrom(((TypePair) obj).b);
        } else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        return 1;
    }

    public static void main(String[] args) {
        TypePair a = new TypePair(Number.class, String.class);
        TypePair b = new TypePair(12, "hello");

        Map<TypePair, Boolean> test = new HashMap<>();
        test.put(a, true);

        System.out.println(a.hashCode() == b.hashCode());
        System.out.println(a.equals(b));
        System.out.println("und? " + test.get(a));
        System.out.println("und? " + test.get(b));
    }
}

此代码打印:

true
true
und? true
und? null

您对 equals() 的实现违反了契约(它不是对称的),这就是它无法正常工作的原因。

您需要使用类似的东西:

@Override
public boolean equals(Object obj) {
    if (obj instanceof TypePair) {
        TypePair objTypePair = (TypePair) obj;
        return a            .isAssignableFrom(objTypePair.a) && b            .isAssignableFrom(objTypePair.b) ||
               objTypePair.a.isAssignableFrom(a)             && objTypePair.b.isAssignableFrom(b);
    } else {
        return false;
    }
}