103 votes

Copie peu profonde d'une carte en Java

Si j'ai bien compris, il existe deux manières (peut-être d'autres également) de créer une copie superficielle d'un Map en Java:

 Map<String, Object> data = new HashMap<String, Object>();
Map<String, Object> shallowCopy;

// first way
shallowCopy = new HashMap<String, Object>(data);

// second way
shallowCopy = (Map<String, Object>) ((HashMap<String, Object>) data).clone();
 

Une façon est-elle préférable à une autre, et si oui, pourquoi?

Une chose à noter est que la deuxième façon donne un avertissement "Distribution incontrôlée". Il faut donc ajouter @SuppressWarnings("unchecked") pour le contourner, ce qui est un peu irritant (voir ci-dessous).

 @SuppressWarnings("unchecked")
public Map<String, Object> getDataAsMap() {
    // return a shallow copy of the data map
    return (Map<String, Object>) ((HashMap<String, Object>) data).clone();
}
 

106voto

polygenelubricants Points 136838

Il est toujours préférable de copier à l'aide d'un constructeur de copie. clone() en Java est cassé (voir DONC: Comment remplacer méthode clone?).

Josh Bloch sur le Design - Constructeur de Copie contre le Clonage

Si vous avez lu l'article sur le clonage dans mon livre, surtout si vous lisez entre les lignes, vous savez que je pense que clone est profondément brisé. [...] C'est une honte qu' Cloneable est cassé, mais ça arrive.

Bloch (qui a conçu et mis en œuvre le cadre pour la Collecte) est même allé plus loin en disant qu'il n'offre à l' clone() méthode juste "parce que les gens attendent". Il n'a PAS réellement vous recommandons de l'utiliser.


Je pense que le débat plus intéressant est de savoir si un constructeur de copie est meilleure qu'une copie de l'usine, mais c'est un autre débat tout à fait.

60voto

Luca Fagioli Points 2885

Aucun des deux: le constructeur que vous faites référence n'est la propriété de la HashMap (ainsi qu'à d'autres) de la mise en œuvre d'une Carte, mais pas à l'interface de la Carte elle-même (par exemple, considérons le Fournisseur de la mise en œuvre de l'interface de la Carte: vous ne trouverez pas que constructeur).

D'autre part, il n'est pas conseillé d'utiliser l' clone() méthode, comme l'a expliqué Josh Bloch.

Dans le respect de l'interface de la Carte (et de votre question, dans laquelle vous demandez comment faire une copie de Carte, pas une table de hachage), vous devez utiliser la Carte#putAll():

Les Copies de tous les mappages de la carte spécifiée pour cette carte (facultatif). L'effet de cet appel est équivalent à celui de l'appel de put(k, v) sur cette carte une fois pour chaque mappage à partir de la clé k à la valeur v dans la carte spécifiée.

Exemple:

// HashMap here, but it works for every implementation of the Map interface
Map<String, Object> data = new HashMap<String, Object>();
Map<String, Object> shallowCopy = new HashMap<String, Object>();

shallowCopy.putAll(data);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X