Guava calcula el código hash de un conjunto como este:
static int hashCodeImpl(Set<?> s) { int hashCode = 0; for(Iterator var2 = s.iterator(); var2.hasNext(); hashCode = ~(~hashCode)) { Object o = var2.next(); hashCode += o != null ? o.hashCode() : 0; } return hashCode; }esto es eficiente y elegante: usamos una operación conmutativa (suma) para "mezclar" los códigos hash de los objetos, de modo que obtengamos el mismo valor independientemente del orden en que iteramos sobre los elementos.
De lo que no estoy seguro es de la condición de actualización en el ciclo for: hashCode = ~(~hashCode) parece no tener efecto (el inspector de código de IntelliJ sugiere simplificar la expresión y luego eliminar la autoasignación).
¿Qué está sucediendo?
Aunque sigue siendo un poco críptico, el código fuente más reciente lo explica (introducido por 86aa9f0 ):
hashCode = ~~hashCode; // Needed to deal with unusual integer overflow in GWT.