同样的输入,为什么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()方法的。
最佳实践
不要依赖Idea IDE自动生成的hashCode方法。
如果有数组的话,用数组用Arrays.hashCode()包起来,然后再作为Objects.hash()方法的参数。
hashCode改成下面的实现就OK了!
@Override public int hashCode() { return Objects.hash(methodName, Arrays.hashCode(parameterTypes), ignoreParameterTypes); }