Las otras respuestas explican adecuadamente por qué falla, pero ninguna de ellas aborda cómo escribir código que es menos propenso a errores en este tema. Tener que recordar para agregar tipos-moldes (sin ayuda del compilador), sufijo primitivas con L y así sucesivamente no es aceptable en mi humilde opinión.
Recomiendo usar la biblioteca de colecciones GNU trove cuando tiene primitivas (y en muchos otros casos). Por ejemplo, hay un TLongLongHashMap que almacena cosas interalmente como longitudes primitivas. Como resultado, nunca se termina con el boxeo/unboxing, y nunca termina con comportamientos inesperados:
TLongLongHashMap map = new TLongLongHashMap();
map.put(1L, 45L);
map.containsKey(1); // returns true, 1 gets promoted to long from int by compiler
int x = map.get(1); // Helpful compiler error. x is not a long
int x = (int)map.get(1); // OK. cast reassures compiler that you know
long x = map.get(1); // Better.
y así sucesivamente. No es necesario obtener el tipo correcto, y el compilador le da un error (que puede corregir o anular) si hace algo tonto (intente almacenar un largo en un int).
Las reglas de auto-casting significan que las comparaciones funcionan correctamente, así:
if(map.get(1) == 45) // 1 promoted to long, 45 promoted to long...all is well
Como beneficio adicional, la sobrecarga de memoria y el rendimiento en tiempo de ejecución es mucho mejor.
Quizás no estaba claro. Sé por qué ocurre lo mismo que en el código fuente que hace que suceda de esa manera, había leído el código antes de publicarlo. Mi pregunta era por qué se decidió que debería ser así? –
http://stackoverflow.com/questions/445990/why-is-long-valueof0-equalsinteger-valueof0-false#446911 lo explica de manera más adecuada. Ya que la comparación de Long to Integer para la igualdad puede violar la simetría. –