Beim Durchsuchen des Quellcodes von Guava stieß ich auf den folgenden Code (Teil der Implementierung von hashCodefü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 adjustund hashsind ints. Soweit ich über Java weiß, ~bedeutet dies bitweise Negation adjust = ~~adjustund hash = ~~hashsollte 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 igleich ist Integer.MAX_VALUE. Da dies i <= Integer.MAX_VALUEimmer 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_VALUEwickelt sich um Integer.MIN_VALUE, so negiert das wieder einfach Integer.MIN_VALUEwieder.
-x = (~x) + 1.