wake-up-neo.com

Flache Kopie einer Map in Java

Soweit ich weiß, gibt es verschiedene Möglichkeiten (vielleicht auch andere), um eine flache Kopie eines Map in Java zu erstellen:

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

Wird ein Weg dem anderen vorgezogen und wenn ja, warum?

Eine erwähnenswerte Sache ist, dass der zweite Weg eine "Unchecked Cast" -Warnung gibt. Sie müssen also @SuppressWarnings("unchecked") hinzufügen, um das Problem zu umgehen, was ein wenig irritierend ist (siehe unten).

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

Es ist immer besser, mit einem Kopierkonstruktor zu kopieren. clone() in Java ist defekt (siehe SO: So überschreiben Sie die Klonmethode richtig? ).

Josh Bloch über Design - Copy Constructor versus Cloning

Wenn Sie den Artikel über das Klonen in meinem Buch gelesen haben, insbesondere wenn Sie zwischen den Zeilen lesen, werden Sie wissen, dass ich denke, dass clone zutiefst kaputt ist. [...] Es ist eine Schande, dass Cloneable kaputt ist, aber es passiert.

Bloch (der übrigens das Collection-Framework entworfen und implementiert hat) ging sogar noch weiter und sagte, dass er nur die clone() -Methode bereitstellt, "weil die Leute es erwarten". Er rät davon ab, es überhaupt zu benutzen.


Ich denke, die interessantere Debatte ist, ob ein Kopierkonstruktor besser ist als eine Kopierfabrik, aber das ist eine ganz andere Diskussion.

106

Keiner der beiden: Der Konstruktor , auf den Sie sich beziehen, ist für die HashMap Implementierung eines Map (sowie für andere) definiert. aber nicht für die Map-Schnittstelle selbst (z. B. Provider Implementierung der Map-Schnittstelle: Sie werden diesen Konstruktor nicht finden).

Andererseits ist es nicht ratsam, die Methode clone() zu verwenden, wie von Josh Bloch erklärt.

In Bezug auf die Map-Oberfläche (und auf Ihre Frage, in der Sie gefragt werden, wie eine Map kopiert werden soll, und nicht eine HashMap) sollten Sie Map # putAll () verwenden:

Kopiert alle Zuordnungen von der angegebenen Karte in diese Karte (optionale Operation). Der Effekt dieses Aufrufs entspricht dem Aufruf von put (k, v) für diese Zuordnung einmal für jede Zuordnung von Schlüssel k zu Wert v in der angegebenen Zuordnung.

Beispiel:

// 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);
59
Luca Fagioli

Kopieren Sie eine Karte, ohne die Implementierung zu kennen:

static final Map shallowCopy(final Map source) throws Exception {
    final Map newMap = source.getClass().newInstance();
    newMap.putAll(source);
    return newMap;
}
11
Terris