Java 中的双波浪号 (~~) 是什么意思?
What is the meaning of double tilde (~~) in Java?
在浏览Guava的源代码时,偶然发现了如下一段代码(hashCode
内部classCartesianSet
的部分实现):
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;
}
证实了这一点。假设 Guava 的家伙知道他们在做什么,那么他们这样做肯定是有原因的。问题是什么?
EDIT 正如评论中指出的那样,上面的测试不包括 i
等于 Integer.MAX_VALUE
的情况。由于 i <= Integer.MAX_VALUE
始终为真,我们需要在循环外检查这种情况,以防止它永远循环下去。但是,行
assert Integer.MAX_VALUE == ~~Integer.MAX_VALUE;
产生编译器警告 "Comparing identical expressions",这几乎可以解决问题。
在Java中没有任何意义。
但是该评论说该行专门用于 GWT,这是一种将 Java 编译为 JavaScript 的方法。
在Java脚本中,整数有点像双精度整数。例如,它们的最大值为 2^53。但是 bitwise operators 将数字视为 32 位,这正是您在此代码中想要的。换句话说,~~hash
在 JavaScript 中表示 "treat hash
as a 32-bit number"。具体来说,它丢弃除底部 32 位以外的所有位(因为按位 ~
运算符仅查看底部 32 位),这与 Java 的溢出工作方式相同。
如果你没有那个,对象的散列码会有所不同,这取决于它是在 Java-land 还是在 JavaScript land 中计算(通过 GWT 编译) .
在浏览Guava的源代码时,偶然发现了如下一段代码(hashCode
内部classCartesianSet
的部分实现):
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;
}
证实了这一点。假设 Guava 的家伙知道他们在做什么,那么他们这样做肯定是有原因的。问题是什么?
EDIT 正如评论中指出的那样,上面的测试不包括 i
等于 Integer.MAX_VALUE
的情况。由于 i <= Integer.MAX_VALUE
始终为真,我们需要在循环外检查这种情况,以防止它永远循环下去。但是,行
assert Integer.MAX_VALUE == ~~Integer.MAX_VALUE;
产生编译器警告 "Comparing identical expressions",这几乎可以解决问题。
在Java中没有任何意义。
但是该评论说该行专门用于 GWT,这是一种将 Java 编译为 JavaScript 的方法。
在Java脚本中,整数有点像双精度整数。例如,它们的最大值为 2^53。但是 bitwise operators 将数字视为 32 位,这正是您在此代码中想要的。换句话说,~~hash
在 JavaScript 中表示 "treat hash
as a 32-bit number"。具体来说,它丢弃除底部 32 位以外的所有位(因为按位 ~
运算符仅查看底部 32 位),这与 Java 的溢出工作方式相同。
如果你没有那个,对象的散列码会有所不同,这取决于它是在 Java-land 还是在 JavaScript land 中计算(通过 GWT 编译) .