Al examinar el código fuente de Guava, me encontré con el siguiente código (parte de la implementación de hashCodela 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 adjusty hashson ints. Por lo que sé acerca de Java, ~mediante la negación bit a bit, por lo que adjust = ~~adjust, y hash = ~~hashdeberí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 ies igual Integer.MAX_VALUE. Como i <= Integer.MAX_VALUEsiempre 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.
fuente

Integer.MAX_VALUE. Contraste con-(-Integer.MIN_VALUE) != Integer.MIN_VALUE.-Integer.MIN_VALUEse envuelveInteger.MIN_VALUE, negando eso nuevamente, simplemente produceInteger.MIN_VALUEnuevamente.-x = (~x) + 1.Respuestas:
En Java, no significa nada.
Pero ese comentario dice que la línea es específicamente para GWT, que es una forma de compilar Java a JavaScript.
En JavaScript, los enteros son como dobles-que-actúan como enteros. Tienen un valor máximo de 2 ^ 53, por ejemplo. Pero los operadores bit a bit tratan los números como si fueran de 32 bits, que es exactamente lo que quieres en este código. En otras palabras,
~~hashdice "tratarhashcomo un número de 32 bits" en JavaScript. Específicamente, descarta todos menos los 32 bits inferiores (dado que los~operadores bit a bit solo miran los 32 bits inferiores), que es idéntico a cómo funciona el desbordamiento de Java.Si no tuviera eso, el código hash del objeto sería diferente dependiendo de si se evalúa en Java-Land o en JavaScript Land (a través de una compilación GWT).
fuente
|0o~~suena como si no fuera difícil, aunque no sé cuál sería el éxito en el rendimiento (tendría que agregarlo en cada paso de cada expresión). No sé cuáles fueron las consideraciones de diseño. Fwiw, la inconsistencia está documentada en la página de compatibilidad de GWT .hashCodees extraño porque deliberadamente corteja, o incluso espera, que ocurra un desbordamiento. El único lugar donde puede observar inconsistencias es donde se desbordaría un int Java normal, que no es un problema que aparece en la mayoría del código; es relevante en este caso extraño.