Beim Durchsuchen des Quellcodes von Guava bin ich auf das folgende Stück Code gestoßen (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 bitweise Negation, also adjust = ~~adjust
und hash = ~~hash
sollte die Variablen unverändert lassen. Ausführen des kleinen Tests (natürlich mit aktivierten Behauptungen),
for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
assert i == ~~i;
}
bestätigt dies. Angenommen, die Guava-Jungs wissen, was sie tun, muss es einen Grund für sie geben, dies zu tun. Die Frage ist was?
BEARBEITEN Wie in den Kommentaren erwähnt, enthält der obige Test nicht den Fall, in dem i
gleich Integer.MAX_VALUE
. Seit i <= Integer.MAX_VALUE
immer wahr ist, müssen wir diesen Fall außerhalb der Schleife überprüfen, um zu verhindern, dass er sich für immer wiederholt. Allerdings die Linie
assert Integer.MAX_VALUE == ~~Integer.MAX_VALUE;
ergibt die Compiler-Warnung “Vergleich identischer Ausdrücke”, die es ziemlich genau trifft.
@dr_andonuts Guava ist heutzutage eine ziemliche Standardbibliothek, die man in ein Projekt aufnehmen kann – ich denke, der Rat, weit weg zu laufen, ist fehl am Platz.
– yshavit
19. April 2015 um 23:19 Uhr
Das Assert prüft den Randfall nicht
Integer.MAX_VALUE
. Gegensatz zu-(-Integer.MIN_VALUE) != Integer.MIN_VALUE
.– Franky
20. April 2015 um 7:04 Uhr
@Franky Was maaartinus gesagt hat.
-Integer.MIN_VALUE
wickelt sich umInteger.MIN_VALUE
so dass das erneute Negieren einfach produziertInteger.MIN_VALUE
wieder.– Benutzer743382
20. April 2015 um 8:24 Uhr
@maaartinus, @hvd, danke für den Hinweis. Jetzt erinnere ich mich daran
-x = (~x) + 1
.– Franky
20. April 2015 um 8:51 Uhr
@dr_andonuts Trolling? Warum vor Dingen davonlaufen, die du nicht verstehst. Dafür ist StackOverflow da: um Ihnen beim Lernen zu helfen.
– Jared Burrows
20. April 2015 um 14:58 Uhr