浏览Guava的源代码时,遇到了以下代码(hashCode内部类的实现的一部分CartesianSet):
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;
}
确认这一点。假设番石榴人知道他们在做什么,那么他们一定有理由这样做。问题是什么?
编辑如评论中所指出,上面的测试不包括iequals 的情况Integer.MAX_VALUE。由于i <= Integer.MAX_VALUE始终为真,因此我们需要在循环外检查该大小写,以防止其永远循环。但是,线
assert Integer.MAX_VALUE == ~~Integer.MAX_VALUE;产生编译器警告“比较相同的表达式”,这几乎可以解决这个问题。
                
                42
              
                  这些天来,@dr_andonuts Guava是一个非常标准的库,要包含在项目中-我认为建议不要太远。
                
                
                  
                    —
                    yshavit 2015年
                    
                  
                
              
                  断言不检查边缘情况
                
                  
                    —
                    Franky 
                    
                  
                
              Integer.MAX_VALUE。与对比-(-Integer.MIN_VALUE) != Integer.MIN_VALUE。
                
                  @ maaartinus,@ hvd,感谢您指出这一点。现在我记得了
                
                  
                    —
                    Franky 
                    
                  
                
              -x = (~x) + 1。
                
                  @dr_andonuts拖钓?为什么要逃避您不了解的事情。这就是StackOverflow的目的:帮助您学习。
                
                
                  
                    —
                    Jared Burrows 2015年