자바에서지도의 얕은 사본 쪽보다 선호되며, 그렇다면

내가 이해하는 바와 같이 MapJava에서 얕은 복사본을 만드는 몇 가지 방법이 있습니다 .

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

한 쪽이 다른 쪽보다 선호되며, 그렇다면 그 이유는 무엇입니까?

언급 할 가치가있는 한 가지는 두 번째 방법이 “Unchecked Cast”경고를 제공한다는 것입니다. 따라서 @SuppressWarnings("unchecked")주위를 둘러 보려면 추가 해야합니다. 이는 약간 짜증이납니다 (아래 참조).

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



답변

항상 복사 생성자를 사용하여 복사하는 것이 좋습니다. clone()Java에서 오류가 발생했습니다 (SO : 복제 방법을 올바르게 재정의하는 방법 참조 ).

디자인에 대한 Josh Bloch-복사 생성자 대 복제

내 책에서 복제에 대한 항목을 읽었다면, 특히 줄 사이를 읽으면 내가 clone깊이 깨 졌다고 생각한다는 것을 알 것 입니다. […] Cloneable부서진 것이 부끄러운 일이지만 일어납니다.

Bloch (그런데 Collection 프레임 워크를 설계하고 구현 한 사람)는 clone()“사람들이 기대하기 때문에”방법 만 제공한다고 말하기까지 했습니다. 그는 실제로 사용을 전혀 권장하지 않습니다.


더 흥미로운 논쟁은 복사 생성자가 복사 팩토리보다 나은지 여부라고 생각하지만, 그것은 완전히 다른 논의입니다.


답변

두 가지 중 어느 것도 참조 하는 생성자MapHashMap 구현에 대해 정의되어 있지 않지만 Map 인터페이스 자체에 대해서는 정의되지 않았습니다 (예 : Map 인터페이스 의 Provider 구현을 고려하십시오 . 생성자를 찾지 못함).

반면 clone()에 Josh Bloch가 설명한대로이 방법 을 사용하는 것은 권장되지 않습니다 .

Map 인터페이스 (및 HashMap이 아닌 Map 복사 방법을 묻는 질문)와 관련하여 Map # putAll () 을 사용해야합니다 .

지정된 맵의 모든 매핑을이 맵에 복사합니다 (선택적 작업). 이 호출의 효과는 지정된 맵에서 키 k에서 값 v 로의 각 매핑에 대해이 맵에서 put (k, v)를 한 번씩 호출하는 것과 같습니다.

예:

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


답변

구현을 모르고지도를 복사합니다.

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


답변