J'ai un tableau 2D d'entiers. Je veux qu'ils soient mis dans un HashMap. Mais je veux accéder aux éléments du HashMap basé sur Array Index. Quelque chose comme:
Pour A [2] [5], map.get(2,5)
qui renvoie une valeur associée à cette clé. Mais comment créer un hashMap avec une paire de clés? Ou en général, plusieurs clés: Map<((key1, key2,..,keyN), Value)
de manière à pouvoir accéder à l'élément avec get (key1, key2, ... keyN).
EDIT: 3 ans après avoir posté la question, je veux y ajouter un peu plus
Je suis tombé sur un autre moyen pour NxN matrix
.
Les indices de tableau i
et j
peuvent être représentés comme un seul de key
la manière suivante:
int key = i * N + j;
//map.put(key, a[i][j]); // queue.add(key);
Et les indices peuvent être récupérés à partir du key
de cette manière:
int i = key / N;
int j = key % N;
Réponses:
Il existe plusieurs options:
2 dimensions
Carte des cartes
Objet clé wrapper
La mise en œuvre
equals()
ethashCode()
est cruciale ici. Ensuite, vous utilisez simplement:et:
Table
depuis GuavaTable
utilise la carte des cartes ci- dessous.N dimensions
Notez que la
Key
classe spéciale est la seule approche qui s'adapte à n dimensions. Vous pourriez également envisager:mais c'est terrible du point de vue des performances, ainsi que de la lisibilité et de l'exactitude (pas de moyen facile d'appliquer la taille de la liste).
Jetez peut-être un œil à Scala où vous avez des tuples et des
case
classes (en remplaçant toute laKey
classe par une seule ligne).la source
Map.Entry<K, V>
comme clé?Map<Pair<Key1, Key2>, Value>
?hashCode()
peut également être implémenté avec une seule ligne commeObjects.hash(x,y)
Lorsque vous créez votre propre objet de paire de clés, vous devez faire face à certaines choses.
Tout d'abord, vous devez être conscient de la mise en œuvre
hashCode()
etequals()
. Vous devrez le faire.Deuxièmement, lors de la mise en œuvre
hashCode()
, assurez-vous de comprendre comment cela fonctionne. L'exemple d'utilisateur donnéest en fait l'une des pires implémentations que vous puissiez faire. La raison est simple: vous avez beaucoup de hachages égaux! Et le
hashCode()
devrait renvoyer des valeurs int qui ont tendance à être rares, uniques au mieux. Utilisez quelque chose comme ceci:Ceci est rapide et renvoie des hachages uniques pour les clés entre -2 ^ 16 et 2 ^ 16-1 (-65536 à 65535). Cela convient à presque tous les cas. Très rarement, vous êtes hors de ces limites.
Troisièmement, lors de la mise en œuvre,
equals()
sachez également à quoi il sert et soyez conscient de la façon dont vous créez vos clés, car ce sont des objets. Souvent, vous ne faites pas inutile si les déclarations provoquent vous aurez toujours le même résultat.Si vous créez des clés comme ceci:
map.put(new Key(x,y),V);
vous ne comparerez jamais les références de vos clés. Parce qu'à chaque fois que vous voudrez accéder à la carte, vous ferez quelque chose commemap.get(new Key(x,y));
. Par conséquent, vousequals()
n'avez pas besoin d'une déclaration commeif (this == obj)
. Cela n'arrivera jamais .Au lieu de
if (getClass() != obj.getClass())
votreequals()
meilleure utilisationif (!(obj instanceof this))
. Il sera valable même pour les sous-classes.Donc, la seule chose que vous devez comparer est en fait X et Y. La meilleure
equals()
implémentation dans ce cas serait donc:Donc, à la fin, votre classe de clé est comme ceci:
Vous pouvez donner vos indices de dimension
X
etY
un niveau d'accès public, car ils sont définitifs et ne contiennent pas d'informations sensibles. Je ne suis pas sûr à 100% si leprivate
niveau d'accès fonctionne correctement dans tous les cas lors de la conversion du fichierObject
en aKey
.Si vous vous interrogez sur la finale, je déclare n'importe quoi comme final dont la valeur est fixée à l'instanciation et ne change jamais - et est donc une constante d'objet.
la source
Vous ne pouvez pas avoir une carte de hachage avec plusieurs clés, mais vous pouvez avoir un objet qui prend plusieurs paramètres comme clé.
Créez un objet appelé Index qui prend une valeur x et y.
Alors ayez votre
HashMap<Index, Value>
pour obtenir votre résultat. :)la source
hashCode
etequals
.Implémenté dans les collections communes MultiKeyMap
la source
Deux possibilités. Soit utiliser une clé combinée:
Ou une carte de la carte:
la source
hashCode
et lesequals
méthodes.Utilisez a
Pair
comme touches pour leHashMap
. JDK n'a pas de paire, mais vous pouvez soit utiliser une bibliothèque tierce telle que http://commons.apache.org/lang, soit écrire votre propre modèle de paire.la source
Créez une classe de valeur qui représentera votre clé composée, telle que:
en prenant soin de passer outre
equals()
ethashCode()
correctement. Si cela semble demander beaucoup de travail, vous pouvez envisager des conteneurs génériques prêts à l'emploi, tels que ceuxPair
fournis par apache commons entre autres.Il y a aussi beaucoup de questions similaires ici, avec d'autres idées, telles que l'utilisation de la table de Guava , bien que cela permette aux clés d'avoir différents types, ce qui pourrait être excessif (en termes d'utilisation de la mémoire et de complexité) dans votre cas, car je comprends que vos clés sont toutes les deux des entiers.
la source
S'il s'agit de deux entiers, vous pouvez essayer une astuce rapide et sale: en
Map<String, ?>
utilisant la touche commei+"#"+j
.Si la clé
i+"#"+j
est la même quej+"#"+i
essayezmin(i,j)+"#"+max(i,j)
.la source
String
avec des conséquences hilarantes.i#j = j#i
quandi == j
donc en utilisant l'min/max
astuce ne le fera pas.5#5
et5#5
échangés?5#3
avoir le même hachage3#5
, alors vous utilisez min / max pour appliquer3#5
dans cet ordre.Vous pouvez également utiliser l' implémentation de table goyave pour cela.
Table représente une carte spéciale dans laquelle deux clés peuvent être spécifiées de manière combinée pour faire référence à une seule valeur. Cela revient à créer une carte de cartes.
la source
Vous pouvez créer votre objet clé comme ceci:
classe publique MapKey {
}
L'avantage de ceci est que cela garantira toujours que vous couvriez également tous les scénarios d'égal.
REMARQUE : vos key1 et key2 doivent être immuables. Ce n'est qu'alors que vous pourrez construire un objet clé stable.
la source
nous pouvons créer une classe pour passer plus d'une clé ou valeur et l'objet de cette classe peut être utilisé comme paramètre dans la carte.
la source
Vous pouvez le télécharger à partir du lien ci-dessous: https://github.com/VVS279/DoubleKeyHashMap/blob/master/src/com/virtualMark/doubleKeyHashMap/DoubleKeyHashMap.java
https://github.com/VVS279/DoubleKeyHashMap
Vous pouvez utiliser une clé double: valeur hashmap,
la source