Beim Durchsuchen des Quellcodes von Guava stieß ich auf den folgenden Code (Teil der Implementierung von hashCode
für die innere Klasse 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;
Beide von adjust
und hash
sind int
s. Soweit ich über Java weiß, ~
bedeutet dies bitweise Negation adjust = ~~adjust
und hash = ~~hash
sollte die Variablen unverändert lassen. Ausführen des kleinen Tests (mit aktivierten Zusicherungen natürlich),
for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
assert i == ~~i;
}
bestätigt dies. Vorausgesetzt, die Guaven wissen, was sie tun, muss es einen Grund für sie geben, dies zu tun. Die Frage ist was?
BEARBEITEN Wie in den Kommentaren ausgeführt, enthält der obige Test nicht den Fall, in dem i
gleich ist Integer.MAX_VALUE
. Da dies i <= Integer.MAX_VALUE
immer der Fall ist, müssen wir diesen Fall außerhalb der Schleife überprüfen, um zu verhindern, dass er für immer wiederholt wird. Allerdings ist die Linie
assert Integer.MAX_VALUE == ~~Integer.MAX_VALUE;
gibt die Compiler-Warnung "Vergleichen identischer Ausdrücke" aus, die es so ziemlich nagelt.
Integer.MAX_VALUE
. Kontrast zu -(-Integer.MIN_VALUE) != Integer.MIN_VALUE
.
-Integer.MIN_VALUE
wickelt sich um Integer.MIN_VALUE
, so negiert das wieder einfach Integer.MIN_VALUE
wieder.
-x = (~x) + 1
.