Quel est le moyen le plus rapide pour supprimer un élément à partir d'une Carte en valeur en Java?
Quel est le moyen le plus rapide pour supprimer un élément à partir d'une Carte en valeur en Java?
Actuellement, je suis en utilisant:
DomainObj valueToRemove = new DomainObj();
String removalKey = null;
for (Map.Entry<String, DomainObj> entry : map.entrySet()) {
if (valueToRemove.equals(entry.getValue())) {
removalKey = entry.getKey();
break;
}
}
if (removalKey != null) {
map.remove(removalKey);
}
- Je suis à l'aide de Java HashMap
- pourquoi vous enlevez l'élément dans si l'état? est-il dangereux?
Vous devez vous connecter pour publier un commentaire.
Sans l'aide d'un Bi-directionnelle de la carte (commons-collections et google collections en avez), vous êtes coincé avec une itération de la Carte
Correcte et rapide one-liner serait:
Étrange que la plupart des exemples ci-dessus supposent la
valueObject
être unique.Voici une solution en ligne:
C'est probablement plus rapide que de définir votre propre itérateur, depuis le JDK code de collection a été considérablement optimisé.
Comme d'autres l'ont mentionné, bimap aura plus rapide de la valeur supprime, si elle nécessite plus de mémoire et prend plus de temps à se remplir. Aussi, un bimap ne fonctionne que lorsque les valeurs sont uniques, ce qui peut ou peut ne pas être le cas dans votre code.
Si vous ne disposez pas d'un revers de la carte, j'irais pour un itérateur.
référence à Comment filtrer "Null" valeurs de HashMap<String, String>?, nous pouvons le faire à la suite de java 8:
Vous pouvez toujours utiliser les valeurs de la collection, depuis les modifications apportées à la collection entraînera le changement se reflète dans la carte. Donc, si vous étiez à la Carte d'appel d'offres.les valeurs de().supprimer(valueToRemove) qui devrait fonctionner - mais je ne sais pas si vous verrez une performance supérieure à celle que vous avez avec cette boucle. Une idée serait d'étendre ou de remplacer la carte de la classe telles que la sauvegarde de la collection est alors toujours triés par valeur - qui vous permettent de faire une recherche binaire sur la valeur qui peut être plus rapide.
Edit: C'est essentiellement le même que Alcon réponse, sauf que je ne pense pas que sa va fonctionner depuis le entrySet est toujours en cours d'être commandé par clé - dans ce cas, vous ne pouvez pas appeler .remove() avec la valeur.
C'est aussi en supposant que la valeur est censée être unique ou que vous souhaitez supprimer tous les doublons de la Carte ainsi.
je voudrais utiliser ce
edit:
parce que les objets sont référencés par "pointeur" et non par valeur.
N
Si vous n'avez aucun moyen de trouver la clé de la DomainObj, alors je ne vois pas comment vous pouvez l'améliorer. Il n'y a pas de méthode intégrée pour obtenir la clé de la valeur, de sorte que vous ont pour parcourir la carte.
Si c'est quelque chose que vous êtes en train de faire tout le temps, vous pouvez maintenir deux cartes (string->DomainObj et DomainObj->Key).
Comme la plupart des autres affiches ont dit, c'est généralement un O(N), parce que vous allez avoir à regarder à travers l'ensemble de la liste des valeurs de la table de hachage, peu importe. @tackline a la bonne solution pour le maintien de l'utilisation de la mémoire en O(1) (je lui ai donné un vote pour que).
Votre autre option consiste à sacrifier de l'espace mémoire pour des raisons de rapidité. Si votre carte est de taille raisonnable, vous pouvez stocker deux cartes en parallèle.
Si vous avez une Carte de la maintenir à une Carte en parallèle. Lorsque vous insérez/retirez sur une carte, de le faire sur les autres aussi. Accordé ce est plus laid parce que vous êtes gaspiller de l'espace et vous devrez assurez-vous que le "hashCode" méthode de DomainObj est écrit correctement, mais votre temps de retrait des gouttes de O(N) à O(1) car vous pouvez la recherche de la clé/objet de la cartographie en temps constant les deux sens.
Généralement pas la meilleure solution, mais si votre préoccupation numéro un est la vitesse, je pense que c'est probablement aussi vite que vous allez obtenir.
====================
Addendum: C'est essentiellement ce que @msaeed suggéré de simplement sans la troisième partie de la bibliothèque.
Une courte utilisation d'un itérateur est d'utiliser les valeurs de() itérateur.
Nous savons que cette situation se présente rarement, mais il est extrêmement utile. Je vais vous préférez
BidiMap
de org.apache.commons.collections .Je ne pense pas que cela se produira qu'une seule fois dans la durée de vie de votre application.
Donc ce que je voudrais faire, c'est de déléguer à un autre objet, la responsabilité de maintenir une référence pour les objets ajoutés à la carte.
Donc, la prochaine fois vous avez besoin de le retirer, vous utilisez le "revers de la carte" ...
C'est beaucoup beaucoup plus rapide que l'itération.
Évidemment, vous devez les garder synchronisés. Mais il ne devrait pas être si difficile, si vous refector votre code pour avoir un objet d'être responsable de l'état de la carte.
Rappelez-vous qu'en programmation orientée objet, nous avons des objets qui ont un état et le comportement. Si vos données est de passer des variables de tous sur la place, vous êtes en train de créer inutile de dépendances entre les objets
Oui, Il vous faudra un certain temps pour corriger le code, mais le temps passé à la correction, vous permettra d'économiser beaucoup de maux de tête à l'avenir. Pensez à ce sujet.