同样的输入,为什么Objects.hash()方法返回的hash值每次不一样?

背景

开发过程中发现一个问题,项目中用Set保存AopMethod对象用于去重,但是发现即使往set中添加相同内容的对象,每次也能够添加成功。

AopMethod类的部分代码如下:

public class AopMethod {
    private String methodName;
    private Class<?>[] parameterTypes = new Class<?>[]{};
    //是否需要忽略掉参数匹配
    private boolean ignoreParameterTypes;
​
    public AopMethod() {
    }
​
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        AopMethod aopMethod = (AopMethod) o;
        return ignoreParameterTypes == aopMethod.ignoreParameterTypes &&
                Objects.equals(methodName, aopMethod.methodName) &&
                Arrays.equals(parameterTypes, aopMethod.parameterTypes);
    }
​
    @Override
    public int hashCode() {
        return Objects.hash(methodName, parameterTypes, ignoreParameterTypes);
    }
}

通过debug发现,对象即使内容完全相同,hashCode每次返回的hash值都是不一样的。

AopMethod{methodName='m81', parameterTypes=[int], ignoreParameterTypes=false} hash:-1850752941
AopMethod{methodName='m81', parameterTypes=[int], ignoreParameterTypes=false} hash:-526785805

equals、hashCode方法是Idea IDE自动生成的,看来,自动生成的不靠谱啊。。。

 

why

Class<?>[] parameterTypes = new Class<?>[]{};

Objects.hash内部会调用hahCode方法,但是parameterTypes为数组,而数组是没有hashCode()方法的。

可参考:https://stackoverflow.com/questions/29955291/why-objects-hash-returns-different-values-for-the-same-input

 

最佳实践

不要依赖Idea IDE自动生成的hashCode方法。

如果有数组的话,用数组用Arrays.hashCode()包起来,然后再作为Objects.hash()方法的参数。

hashCode改成下面的实现就OK了!

    @Override
    public int hashCode() {
        return Objects.hash(methodName, Arrays.hashCode(parameterTypes), ignoreParameterTypes);
    }

 

参考资料

https://stackoverflow.com/questions/29955291/why-objects-hash-returns-different-values-for-the-same-input

posted @ 2019-03-05 17:49  Ye_yang  阅读(5095)  评论(0编辑  收藏  举报