12
votes

En utilisant deux objets (ou plus) comme une clé hashmap

Je veux stocker certains objets dans un hashmap. Le problème est que vous utilisez généralement un seul objet comme clé. (Vous pouvez, par exemple, utiliser une chaîne.) Ce que je veux le faire pour utiliser plusieurs objets. Par exemple, une classe et une chaîne. Y a-t-il un moyen simple et propre de mettre en œuvre cela?


0 commentaires

8 Réponses :


10
votes

J'ai tendance à utiliser une liste xxx


5 commentaires

Non, le hashcode de toute liste (ou au moins tout abstracttractlist , quel arranges.aslist est) est déterminé par les hachons de ses éléments. Je viens de regarder ça parce que j'avais la même pensée.


Facile à faire, mais il a l'inconvénient de ne pas documenter ce qui appartient à la liste. Était c'était la classe, la chaîne; ou la chaîne en premier? ou le nom de classe et la chaîne?


True, mais il existe des moyens de gérer cela, comme la création d'une méthode Static GetHashlist qui le fera pour vous. En outre, je recommanderais certainement la classe clé de Pierre pour des cartes plus longues.


Un autre problème est que les implémentations de hashcode et des égaux dans la liste sont coûteuses par rapport à une classe personnalisée bien mise en œuvre.


Comment? Vous devriez faire les mêmes opérations de toute façon. Il y a une seule déréférence d'objet supplémentaire, mais cela n'est pas susceptible de causer une erreur de cache.



1
votes

Vous pouvez créer une classe de titulaire contenant la classe et la chaîne que vous souhaitez que vous souhaitez les touches.

public class Key {

    public MyClass key_class;
    public String key_string;

    public Key(){
        key_class = new MyClass();
        key_string = "";
    }

}


2 commentaires

Toute classe utilisée comme une clé doit remplacer les égaux () et le hashcode () correctement.


J'aime l'approche, mais l'ajout d'une méthode HASHCODE et Equals est obligatoire pour le cas d'utilisation. Je ferais aussi une immuable.



4
votes

La manière la plus simple que je connaisse est de faire une classe d'emballage et de remplacer Hashmap et est égal. Par exemple:

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();
    }
}


0 commentaires

2
votes

Voulez-vous dire que l'objet sera saisi par deux clés, ou plutôt une clé qui consiste en deux choses.

Si vous voulez le premier cas. C'est-à-dire un objet clé sur deux clés, disons une classe ou un objet, vous devez utiliser deux cartes. xxx

dans le second cas, vous avez besoin d'une carte des cartes, Donc: xxx


0 commentaires

14
votes

Vous devez mettre en œuvre le hachemode et les égaux. S'il s'agit d'un SoyedMap , il doit également implémenter l'interface comparable xxx


0 commentaires

3
votes

Les collections Apache Commons ont une carte multikey qui pourrait faire le tour pour vous:

HTTPS: / /Commons.apache.org/proper/commons-Collections/apidocs/org/apache/commons/Collections4/keyvalue/Multikey.html

On dirait qu'il manipulera jusqu'à 5 "clés".


0 commentaires

0
votes

Il y a quelques endroits où les gens suggèrent de créer une classe "clé" contenant les autres, je suis totalement d'accord. Il suffit de penser que j'ajouterais un indice utile.

Si vous utilisez Eclipse ou NetBeans, ils ont une bonne option - vous pouvez dire à Eclipse de créer des méthodes d'équivalence et de code HASHCODE basées sur un ou plusieurs membres. Vous venez de sélectionner simplement le membre (ou les membres) que vous souhaitez récupérer par et NB crée la plupart du code que vous auriez besoin d'écrire pour vous. P>

Bien sûr lorsque je veux juste récupérer par un objet, Je déléguais souvent simplement le hashcode et équiper des méthodes à cet objet (la délégation des équivalions peut être problématique car elle signifierait que l'un de vos classes "titulaires de clé" serait égal à l'objet qui est la clé, mais c'est assez facile à fixer (et plus facilement 't généralement effectivement effectivement quelque chose de toute façon) p>

SO SO SE SOP TOP DE MA TÊTE: P>

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();
    }
}


0 commentaires

0
votes

On peut résoudre ce problème à l'aide de la collection Commons de Apache Lib's multikey code> classe . Voici un exemple 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)); 


1 commentaires

Notez que cela duplicate La réponse de Clay , bien que vous ayez fourni un exemple.