구아바의 소스 코드를 탐색 할 때 다음 코드 조각 ( 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
들. 나는 자바에 대해 무엇을 알고에서 ~
부정 비트 수단, 그렇게 adjust = ~~adjust
하고 hash = ~~hash
변경되지 않은 변수를 떠나야한다. 작은 테스트 (어설 션이 활성화 된 상태에서) 실행
for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
assert i == ~~i;
}
이것을 확인합니다. 구아바 사람들이 그들이하고있는 일을 알고 있다고 가정하면, 그들이해야 할 이유가 있어야합니다. 문제는 무엇입니까?
편집 주석에서 지적했듯이 위의 테스트에는 i
equals가 포함되지 않습니다 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
.