เมื่อเรียกดูซอร์สโค้ดของ 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มีints จากสิ่งที่ฉันรู้เกี่ยวกับ Java ~หมายถึงการปฏิเสธ bitwise ดังนั้น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;
ให้คำเตือนคอมไพเลอร์ "การเปรียบเทียบนิพจน์ที่เหมือนกัน" ซึ่งเล็บมันสวยมาก
Integer.MAX_VALUEยืนยันไม่ได้ตรวจสอบกรณีที่ขอบ -(-Integer.MIN_VALUE) != Integer.MIN_VALUEตรงกันข้ามกับ
-Integer.MIN_VALUEล้อมรอบไปInteger.MIN_VALUEดังนั้นปฏิเสธว่าอีกครั้งเพียงสร้างInteger.MIN_VALUEอีกครั้ง
-x = (~x) + 1ได้