Quiero almacenar ciertos objetos en un HashMap. El problema es que generalmente usas un solo objeto como clave. (Puede, por ejemplo, usar un String.) Lo que quiero hacer es usar un objeto múltiple. Por ejemplo, una clase y una cadena. ¿Hay una manera simple y limpia de implementar eso?Usando dos (o más) objetos como una clave HashMap
Respuesta
clave Debe implementar el código hash e iguales. Si se trata de un SortedMap, también tiene que implementa la interfaz Comparable
public class MyKey implements Comparable<MyKey>
{
private Integer i;
private String s;
public MyKey(Integer i,String s)
{
this.i=i;
this.s=s;
}
public Integer getI() { return i;}
public String getS() { return s;}
@Override
public int hashcode()
{
return i.hashcode()+31*s.hashcode();
}
@Override
public boolean equals(Object o)
{
if(o==this) return true;
if(o==null || !(o instanceof MyKey)) return false;
MyKey cp= MyKey.class.cast(o);
return i.equals(cp.i) && s.equals(cp.s);
}
public int compareTo(MyKey cp)
{
if(cp==this) return 0;
int i= i.compareTo(cp.i);
if(i!=0) return i;
return s.compareTo(cp.s);
}
@Override
public String toString()
{
return "("+i+";"+s+")";
}
}
public Map<MyKey,String> map= new HashMap<MyKey,String>();
map.put(new MyKey(1,"Hello"),"world");
que tienden a utilizar una lista
map.put(Arrays.asList(keyClass, keyString), value)
Se puede crear una clase de soporte que contiene la clase y la cadena que desea que las teclas.
public class Key {
public MyClass key_class;
public String key_string;
public Key(){
key_class = new MyClass();
key_string = "";
}
}
Probablemente no sea la mejor solución, pero es una posibilidad.
Cualquier clase utilizada como clave necesita anular equals() y hashCode() correctamente. – notnoop
Me gusta el enfoque, pero agregar un código hash y el método igual es obligatorio para el caso de uso. También lo haría inmutable. –
@msaeed y @Jens Schauder, gracias por los consejos. –
La manera más fácil que conozco es hacer una clase contenedora y anular hashmap e iguales. Por ejemplo:
public class KeyClass {
private String element1;
private String element2;
//boilerplate code here
@Override
public boolean equals(Object obj) {
if (obj instanceof KeyClass) {
return element1.equals(((KeyClass)obj).element1) &&
element2.equals(((KeyClass)obj).element2);
}
return false;
}
@Override
public int hashCode() {
return (element1 + element2).hashcode();
}
}
Por supuesto, yo recomendaría usar un StringBuilder y cualquier otra cosa, pero de esta manera se ha anulado los iguales y código hash, lo que permite un control de hash y la igualdad en sus varias claves.
Además, recomendaría hacer los objetos inmutables (no editables) por razones de seguridad, pero eso es pura preferencia.
¿Quiere decir que el objeto estará marcado por dos teclas, o más bien por una clave que consta de dos cosas.
Si quiere el primer caso. Es decir, una objeción marcada por dos teclas, digamos una clase o un objeto, debe usar dos mapas.
Map<Key1, value>
Map<Key2, value>
En el segundo caso se necesita un mapa de los mapas, por lo que:
Map<Key1, Map<Key2, value>>
Apache Commons Collections tiene un mapa multicircuito que podría hacer el truco para usted:
Parece como si manejará hasta 5 "claves".
Hay algunos lugares donde la gente sugiere crear una clase "Clave" que contenga las otras, estoy totalmente de acuerdo. Solo pensé en agregar una sugerencia útil.
Si usa eclipse o netbeans, tienen una buena opción: puede decirle a Eclipse que cree métodos iguales y de código hash basados en uno o más miembros. Así que solo selecciona el miembro (o miembros) que desea recuperar y NB crea la mayor parte del código que necesitaría escribir para usted.
por supuesto cuando solo quiero recuperar por un objeto, a menudo solo delegado el código hash e iguala los métodos a ese objeto (delegar iguales podría ser problemático porque significaría que una de las clases "titular de clave" sería igual al objeto que es que es clave, pero eso es bastante fija fácilmente (y no habría normalmente efectuar nada de todos modos)
tan fuera de la parte superior de mi cabeza:
class KeyHolder {
public final String key;
public final Object storeMe;
public KeyHolder(String key, Object storeMe) {
this.key=key;
this.storeMe=storeMe;
}
public equals(Object o) {
return (o instanceof KeyHolder && ((KeyHolder)o).key.equals(key));
}
public hashcode() {
return key.hashCode();
}
}
eso es todo lo que hay que hacer, y eclipse hará las dos últimas por ti si lo pides.
Por cierto, sé que tengo miembros públicos, un miembro final público es exactamente lo mismo que tener un captador: realmente no es una idea terrible. Últimamente estoy empezando a utilizar este patrón en pequeñas clases de utilidad como esta. Si el miembro no fuera final, sería peor porque sería como tener un colocador (algo que trato de evitar en estos días).
Uno puede resolver este problema usando la colección de commons de apache MultiKey
class de lib. Aquí hay un ejemplo simple:
import org.apache.commons.collections.keyvalue.MultiKey;
HashMap map = new HashMap();
MultiKey multiKey = new MultiKey(key1, key2);
map.put(multikey,value);
//to get
map.get(new MultiKey(key1,key2));
Tenga en cuenta que esto duplica [respuesta de Clay] (http://stackoverflow.com/a/1190244/157247), a pesar de que usted ha proporcionado un ejemplo. –
- 1. ArrayList como clave en Hashmap
- 2. Crear un hashmap con una doble clave
- 3. Java HashMap o IdentityHashMap
- 4. Unión de dos o más (hash) mapea
- 5. Configuración de la clase propia como clave en Java Hashmap
- 6. ¿La manera más pitónica de asignar argumentos de palabra clave usando una variable como palabra clave?
- 7. java HashMap iteración clave
- 8. Java HashMap Quitar clave/valor
- 9. jquery usando objetos como filtros
- 10. Java: razones para permitir null como clave HashMap
- 11. Obtener clave de un HashMap usando el valor
- 12. Devolviendo dos o más valores desde una función
- 13. Usando PHPUnit, ¿cómo se prueba solo dos o más grupos?
- 14. Cómo usar dos números como una clave de mapa
- 15. dos o más RelativeLayout anidado
- 16. Combinar dos (o más) PDF's
- 17. Actualización de Java HashMap clave
- 18. ¿Cómo puedo inicializar una matriz de objetos cuyo constructor requiere dos o más argumentos?
- 19. Crear un HashMap en Scala a partir de una lista de objetos sin bucle
- 20. Usando un objeto como clave para NSDictionary
- 21. Uso de HashMap con la clave personalizada
- 22. Comprobación de existencia de clave en HashMap
- 23. Java HashMap: ¿Cómo obtener una clave y valor por índice?
- 24. Dos o más PathParts encadenados (catalizador)
- 25. ¿Cómo crear constantes Javascript como propiedades de los objetos usando la palabra clave const?
- 26. php foreach como clave, cada dos números como un grupo
- 27. Gee HashMap que contiene métodos como valores
- 28. Evaluando en dos o más listas
- 29. Usando ID de objeto como hash para objetos en Python
- 30. Agregar 2 o más objetos a JFrame
¿El hashcode de Array.asList no es específico de esa lista? –
No, el código hash de cualquier 'Lista' (o al menos cualquier' AbstractList', que 'Arrays.asList' es) está determinado por los códigos hash de sus elementos. Lo busqué porque tenía el mismo pensamiento. –
Fácil de hacer, pero tiene el inconveniente de no documentar lo que pertenece a la lista. ¿Era clase, cuerda? o la cadena primero? o el nombre de clase y la cadena? –