La respuesta a la pregunta 2 es fácil: sí, puede usar cualquier Objeto que desee. Los mapas que tienen claves de tipo String son ampliamente utilizados porque son estructuras de datos típicas para nombrar servicios. Pero en general, puede asignar dos tipos como Map<Car,Vendor>
o Map<Student,Course>
.
Para el método hashcode() es como se contestó antes: siempre que anule equals(), debe anular hashcode() para cumplir el contrato. Por otro lado, si está contento con la implementación estándar de equals(), entonces no debe tocar hashcode() (porque eso podría romper el contrato y resultar en códigos hash idénticos para objetos desiguales).
nota lateral práctica: eclipse (y probablemente otros IDEs también) puede generar automáticamente un par de implementaciones equals() y hashcode() para su clase, solo en función de los miembros de la clase.
Editar
Por su pregunta adicional: sí, exactamente. Mire el código fuente para HashMap.get (clave Object); llama a la llave.hashcode para calcular la posición (bin) en el hashtable interno y devuelve el valor en esa posición (si hay uno).
Pero tenga cuidado con los métodos hashcode/equals 'hechos a mano': si utiliza un objeto como clave, asegúrese de que el código no cambia posteriormente, de lo contrario, ya no encontrará los valores mapeados. En otras palabras, los campos que usa para calcular iguales y hashcode deben ser finales (o 'inmutables' después de la creación del objeto).
Supongamos que tenemos un contacto con String name
y String phonenumber
y usamos ambos campos para calcular equals() y hashcode(). Ahora creamos "John Doe" con su número de teléfono móvil y lo asignamos a su tienda de Donut favorita. hashcode() se usa para calcular el índice (bin) en la tabla hash y ahí es donde se almacena la tienda donut.
Ahora nos enteramos de que tiene un nuevo número de teléfono y cambiamos el campo del número de teléfono del objeto John Doe. Esto da como resultado un nuevo hashcode. Y este código hash se resuelve en un nuevo índice de tablas hash, que generalmente no es el lugar donde se almacenó la tienda favorita Donut de John Does.
El problema es claro: en este caso, queríamos asignar "John Doe" a la tienda Donut, y no a "John Doe con un número de teléfono específico". Por lo tanto, debemos ser cuidadosos con equals/hashcode autogenerados para asegurarnos de que sean lo que realmente queremos, ya que pueden usar campos no deseados, lo que introduce problemas con HashMaps y HashSets.
Editar 2
Si agrega un objeto a un HashSet, el objeto es la clave para la tabla hash interna, el valor se establece pero no usado (sólo una instancia estática del objeto). Aquí está la implementación de openjdk 6 (b17):
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
private transient HashMap<E,Object> map;
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
"el valor está establecido pero no utilizado (solo una instancia estática de Object)." No entendí por completo ... explico ... Y en segundo lugar, en HashSet, si el valor del obj se modifica después ... el problema que mencionaste para HashMap (el hashcode de la clave se cambia, no se puede rastrear) no debería suceder. . ¿derecho? confirmar ... – peakit
marcando esto como hecho .. muy buena explicación ... gracias – peakit