私が理解しているように、JavaでMap
の浅いコピーを作成する方法はいくつかあります(他の方法もあります)。
_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();
_
ある方法が他の方法よりも優先されますか?
言及する価値のあることの1つは、2番目の方法が「未チェックのキャスト」警告を出すことです。そのため、@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()
in Javaは壊れています(SOを参照してください: クローンメソッドを適切にオーバーライドする方法? )。
Josh Bloch on Design-Copy Constructor vs Cloning
私の本でクローン作成に関する項目を読んだ場合、特に行間を読んだ場合、
clone
が深く壊れていると思います。 [...]Cloneable
が壊れているのは残念ですが、それは起こります。
Bloch(ちなみにCollectionフレームワークの設計と実装)は、「人々が期待するから」だけでclone()
メソッドのみを提供していると言っています。彼は実際にそれを使用することをまったく勧めていません。
もっと興味深い議論は、コピーコンストラクターがコピーファクトリより優れているかどうかですが、それはまったく別の議論です。
どちらでもない:参照している constructor は、 HashMap の実装 Map に定義されている(およびその他)ただし、Mapインターフェース自体は対象外です(たとえば、Mapインターフェースの Provider 実装を検討してください。このコンストラクターは見つかりません)。
一方、Josh Blochが説明したように、clone()
メソッドを使用することはお勧めできません。
Mapインターフェース(および、HashMapではなくMapのコピー方法を尋ねる質問)に関しては、 Map#putAll() を使用する必要があります。
指定されたマップからこのマップにすべてのマッピングをコピーします(オプションの操作)。この呼び出しの効果は、指定されたマップのキーkから値vへのマッピングごとに、このマップでput(k、v)を1回呼び出すのと同等です。
例:
// 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;
}