web-dev-qa-db-fra.com

Map.clear () vs nouvelle carte: Laquelle sera la meilleure?

J'ai une carte comme syntaxe comme Map<String, String> testMap = new HashMap<String, String>();. Dans cette carte, il peut y avoir 1000 données.

Lorsque mon application nécessite une nouvelle liste de données, je dois vider la carte. Mais quand j'ai vu le code de Map.clear () comme

/**
     * Removes all of the mappings from this map.
     * The map will be empty after this call returns.
     */
    public void clear() {
        modCount++;
        Entry[] tab = table;
        for (int i = 0; i < tab.length; i++)
            tab[i] = null;
        size = 0;
    }

Je me rends compte que la méthode clear fonctionne en boucle pendant n fois (où n est le nombre de données dans Map). J'ai donc pensé qu'il pourrait y avoir un moyen de redéfinir cette carte en tant que testMap = new HashMap<String, String>(); et que la carte précédemment utilisée sera récupérée.

Mais je ne suis pas sûr que ce sera un bon moyen. Je travaille sur une application mobile.

Pouvez-vous me guider s'il vous plaît?

88
Pankaj Kumar

Question compliquée. Voyons ce qui se passe.

Vous instanciez une nouvelle instance, qui est sauvegardée avec un nouveau tableau. Le ramasse-miettes doit donc effacer toute la clé et les valeurs de la carte précédente, ainsi que la référence à elle-même. Donc, l'algorithme O(n)) est exécuté, mais dans le thread du ramasse-miettes. Pour 1000 enregistrements, vous ne verrez aucune différence. MAIS. La performance guide indique vous que il est toujours préférable de ne pas créer de nouveaux objets , si vous le pouvez. Je choisirais donc la méthode clear().

Quoi qu'il en soit, essayez les deux variantes et essayez de mesurer. Toujours mesurer!

94
Vladimir Ivanov

Lorsque vous dites Map.clear() sur une mappe de taille n... vous demandez au CPG de nettoyer les objets 2*n (Clé et valeur). Lorsque vous dites null à la même carte, vous demandez au GC de nettoyer les objets 2*n+1 (1 pour la carte elle-même). Ensuite, vous devrez créer une nouvelle instance de carte avec encore une surcharge. Alors, allez pour Map.clear(). Il vous sera judicieux de prédéfinir la taille de la carte tout en l'instanciant.

21
Tanveer

Je pensais que la création d'objet dans Java plus cher en termes de mémoire, il est donc préférable d'utiliser .clear(), donc vous utilisez le même objet au lieu d'en créer un nouveau

9
sunriser

L'idée de la méthode clear () est de supprimer les références à d'autres objets de la carte, de sorte que les clés/valeurs ne soient pas bloquées si la "carte est référencée ailleurs".

Mais si votre carte est une carte locale utilisée uniquement par votre code spécifique (c.-à-d. "La carte n'est pas" référencée ailleurs "), utilisez plutôt une nouvelle carte, mais définir 1000 références sur null ne sera pas un grand succès. en tous cas.

5
Suraj Chandran

n'oubliez pas le repeuplement de la carte

si vous ne spécifiez pas la capacité sur la nouvelle carte, vous aurez un peu de surcharge sur la carte nouvellement créée en raison de rehashes (chacun O(n) (à l'époque) et arriver O(log(n)) fois, alors que cela pourrait s’amortir à O(n) total mais s’ils ne se produisent pas en premier lieu, vous sera toujours mieux de)

cela n'arrivera pas avec la carte effacée parce que la capacité ne change pas

2
ratchet freak

Le map.clear () qui supprimera toutes les données. Notez que cela ne supprimera que toutes les entrées, mais conservera le tableau interne utilisé pour stocker les entrées à la même taille (plutôt que de réduire à une capacité initiale). Si vous devez également éliminer cela, le moyen le plus simple consiste à supprimer l'ensemble de HashMap et à le remplacer par une nouvelle instance. Cela ne fonctionne bien sûr que si vous contrôlez qui a un pointeur sur la carte.

Pour récupérer la mémoire, vous devrez laisser le ramasse-miettes faire son travail.

Vos valeurs sont-elles aussi longues? Dans ce cas, vous pouvez envisager une implémentation plus efficace (en mémoire) que le HashMap générique, tel que le TLongLongHashMap présent dans bibliothèque GNU Trove . Cela devrait économiser beaucoup de mémoire.

1
Pratik

Je pense qu’appeler new HashMap () est une meilleure idée car il n’aura pas à traiter autant de choses que l’effacement de la table de hachage. De même, en créant un nouveau hashmap, vous éliminez le risque que le hashmap reste lié au contrôle qui utilise les données, ce qui poserait des problèmes lorsque le hashmap doit être effacé.

1
A. Abiri