เมื่อเรียกดูซอร์สโค้ดของ 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
s จากสิ่งที่ฉันรู้เกี่ยวกับ 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
ได้