最佳答案
在浏览 Guava 的源代码时,我偶然发现了以下代码(内部类 CartesianSet
的 hashCode
实现的一部分) :
int adjust = size() - 1;
for (int i = 0; i < axes.size(); i++) {
adjust *= 31;
adjust = ~~adjust;
// in GWT, we have to deal with integer overflow carefully
}
int hash = 1;
for (Set<E> axis : axes) {
hash = 31 * hash + (size() / axis.size() * axis.hashCode());
hash = ~~hash;
}
hash += adjust;
return ~~hash;
adjust
和 hash
都是 int
。根据我对 Java 的了解,~
意味着按位求负,所以 adjust = ~~adjust
和 hash = ~~hash
应该保持变量不变。运行小型测试(当然是启用断言) ,
for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
assert i == ~~i;
}
证实了这一点。假设番石榴的家伙知道他们在做什么,他们这样做一定是有原因的。问题是什么?
正如评论中指出的,上面的测试不包括 i
等于 Integer.MAX_VALUE
的情况。因为 i <= Integer.MAX_VALUE
总是为真,所以我们需要检查循环外的那个情况,以防止它永远循环下去。但是,这条线呢
assert Integer.MAX_VALUE == ~~Integer.MAX_VALUE;
产生编译器警告“比较相同的表达式”,这很好地解决了这个问题。