Al examinar el código fuente de Guava, me encontré con el siguiente código (parte de la implementación de hashCode
la clase interna 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;
Ambos adjust
y hash
son int
s. Por lo que sé acerca de Java, ~
mediante la negación bit a bit, por lo que adjust = ~~adjust
, y hash = ~~hash
debería salir de las variables sin cambios. Ejecutando la pequeña prueba (con aserciones habilitadas, por supuesto),
for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
assert i == ~~i;
}
confirma esto Suponiendo que los chicos de la guayaba saben lo que están haciendo, debe haber una razón para que lo hagan. La pregunta es qué?
EDITAR Como se señaló en los comentarios, la prueba anterior no incluye el caso donde i
es igual Integer.MAX_VALUE
. Como i <= Integer.MAX_VALUE
siempre es cierto, tendremos que verificar ese caso fuera del bucle para evitar que se repita para siempre. Sin embargo, la linea
assert Integer.MAX_VALUE == ~~Integer.MAX_VALUE;
produce la advertencia del compilador "Comparación de expresiones idénticas", que prácticamente lo clava.
Integer.MAX_VALUE
. Contraste con -(-Integer.MIN_VALUE) != Integer.MIN_VALUE
.
-Integer.MIN_VALUE
se envuelve Integer.MIN_VALUE
, negando eso nuevamente, simplemente produce Integer.MIN_VALUE
nuevamente.
-x = (~x) + 1
.