Jak rozumiem, istnieje kilka sposobów (być może także innych) na utworzenie płytkiej kopii pliku Map
w Javie:
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();
Czy jeden sposób jest preferowany od drugiego, a jeśli tak, to dlaczego?
Warto wspomnieć o tym, że druga metoda daje ostrzeżenie o „Unchecked Cast”. Musisz więc dodać, @SuppressWarnings("unchecked")
aby to obejść, co jest trochę irytujące (patrz poniżej).
@SuppressWarnings("unchecked")
public Map<String, Object> getDataAsMap() {
// return a shallow copy of the data map
return (Map<String, Object>) ((HashMap<String, Object>) data).clone();
}
java
map
clone
shallow-copy
dcp
źródło
źródło
Odpowiedzi:
Zawsze lepiej jest kopiować za pomocą konstruktora kopiującego.
clone()
w Javie jest uszkodzony (patrz SO: Jak poprawnie zastąpić metodę clone? ).Josh Bloch on Design - Copy Constructor versus Cloning
Bloch (który, nawiasem mówiąc, zaprojektował i wdrożył framework Collection) poszedł nawet dalej, mówiąc, że dostarcza
clone()
metody tylko „dlatego, że ludzie tego oczekują”. W rzeczywistości wcale NIE zaleca jego używania.Myślę, że bardziej interesującą debatą jest to, czy konstruktor kopii jest lepszy niż fabryka kopii, ale to zupełnie inna dyskusja.
źródło
Żaden z tych dwóch: konstruktor , do którego się odnosisz, nie jest zdefiniowany dla implementacji HashMap w Map (jak również dla innych), ale nie dla samego interfejsu Map (na przykład rozważ implementację dostawcy interfejsu Map: ty nie znajdzie tego konstruktora).
Z drugiej strony nie zaleca się stosowania tej
clone()
metody, jak wyjaśnia Josh Bloch.W odniesieniu do interfejsu mapy (i twojego pytania, w którym pytasz, jak skopiować mapę, a nie HashMap), powinieneś użyć Map # putAll () :
Przykład:
źródło
Map
która ma konstruktor kopiujący, nie ma powodu, aby nie używać konstruktora kopiującego?putAll
, nie musisz wiedzieć, czyMap
implementacja, której używasz, ma konstruktor kopiujący, czy nie. Tak więc zwykły konstruktor kopiujący dowolnejMap
implementacji jest zbędny.Skopiuj mapę bez znajomości jej implementacji:
źródło
<K,V>
parametrów typu, aby zapewnić bezpieczeństwo typu.