我有几个Map
其本身可能再次包含Map
s(任何类型)。我写了一个带有签名的方法:
public static <K,V> HashMap<K,V> deepCopyHashMap(HashMap<K,V> s);
但是,我现在想概括此代码以支持Map
一般而言,但仍然返回与参数类型相同的对象。所以而不是:
public static <K,V> HashMap<K,V> deepCopyHashMap(HashMap<K,V> s);
public static <K,V> CheckedMap<K,V> deepCopyCheckedMap(CheckedMap<K,V> s);
public static <K,V> TreeMap<K,V> deepCopyTreeMap(TreeMap<K,V> s);
...
etc.
我想要这样的东西:
public static <K,V, M extends Map<K,V>> M<K,V> deepCopyMap(M<K,V> s);
然而,这给了我:
Multiple markers at this line
- The type M is not generic; it cannot be parameterized with arguments <K,
V>
- The type M is not generic; it cannot be parameterized with arguments <K,
V>
如何正确声明方法签名并仍然返回正确类型的对象(内部不使用反射)?
对于这个项目来说,添加更多依赖项确实不是一个选择,所以我更喜欢一个不依赖外部库的解决方案。另外,我还调查了Cloneable
接口,但是它只是一个标记接口(没有实现Map
一般而言)这对我来说没有多大用处。
编辑:
作为参考,这是我的深度复制嵌套代码HashMap
s(代码工作正常):
public static <K,V> HashMap<K,V> deepCopyHashMap(HashMap<K,V> source){
HashMap<K,V> result = new HashMap<K, V>();
for(Map.Entry<K, V> entry : source.entrySet()){
K k = entry.getKey();
V v = entry.getValue();
if(k instanceof HashMap<?,?>){
k = (K) deepCopyHashMap((HashMap<?,?>) k);
}
if(v instanceof HashMap<?,?>){
v = (V) deepCopyHashMap((HashMap<?,?>) v);
}
result.put(k, v);
}
return result;
}
编辑:解决方案
-
这不是一个理想的解决方案。如果嵌套的运行时类型没有默认构造函数,它将失败Map
。我已经用嵌套测试了它HashMap
s 并且运行时类型已正确复制。
@SuppressWarnings("unchecked")
public static <K,V, M extends Map<K,V>> M deepCopyMap(M source) throws InstantiationException, IllegalAccessException{
M result = (M) source.getClass().newInstance();
for(Map.Entry<K, V> entry : source.entrySet()){
K k = entry.getKey();
V v = entry.getValue();
if(k instanceof Map<?,?>){
k = (K) deepCopyMap((Map<?,?>) k);
}
if(v instanceof Map<?,?>){
v = (V) deepCopyMap((Map<?,?>) v);
}
result.put(k, v);
}
return result;
}
-
这更安全,但需要显式列出所有已知类型:
@SuppressWarnings("unchecked")
public static <K,V, M extends Map<K,V>> M deepCopyMap(M source){
M result;
if(source instanceof HashMap){
result = (M) new HashMap<K,V>();
} else {
//fail
}
// etc. add more types here
for(Map.Entry<K, V> entry : source.entrySet()){
K k = entry.getKey();
V v = entry.getValue();
if(k instanceof Map<?,?>){
k = (K) deepCopyMap((Map<?,?>) k);
}
if(v instanceof Map<?,?>){
v = (V) deepCopyMap((Map<?,?>) v);
}
result.put(k, v);
}
return result;
}