在原始类型上使用复制构造函数是有效的:
HashMap<String, String> hashMap = new HashMap(map);
然而,这个解决方案很丑陋,因为类型系统被忽略了。
编辑1:
当你执行
public static void main(String[] args) throws IllegalArgumentException,
InterruptedException, IOException {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("Bla", new Object());
HashMap<String, String> hashMap = new HashMap(map);
System.out.println(hashMap.get("Bla").getClass());
}
如果您遇到"Class Cast Exception"异常:
Exception in thread "main" java.lang.ClassCastException: java.lang.Object cannot be cast to java.lang.String
执行"System.out.println(hashMap.get("Bla").getClass());"时会抛出此异常。
因此,转换实际上是被延迟的。
编辑2:
您可以通过以下方法避免拷贝
HashMap<String, String> hashMap = (HashMap)map
然而,问题仍然存在,就像以下代码所示:
public static void main(String[] args) throws IllegalArgumentException,
InterruptedException, IOException {
HashMap<String, Object> oldMap = new HashMap<String, Object>();
oldMap.put("Bla", new Object());
HashMap<String, String> hashMap = (HashMap)oldMap;
System.out.println(hashMap.get("Bla").getClass());
}
这段代码与EDIT1中的示例类似。
EDIT3:
使用lambda表达式怎么样?
Map<String, Object> map = new HashMap<String, Object>();
final Stream<Map.Entry<String, Object>> entries = map.entrySet()
.stream();
final Function<Map.Entry<String, Object>, String> keyMapper = (
Map.Entry<String, Object> entry) -> entry.getKey();
final Function<Map.Entry<String, Object>, String> valueMapper = (
Map.Entry<String, Object> entry) -> {
final Object value = entry.getValue();
if (value instanceof String) {
return (String) value;
} else {
throw new ClassCastException("Value '" + value + "' of key '"
+ entry.getKey() + "' cannot be cast from type "
+ ((value != null) ? value.getClass().getName() : null)
+ " to type " + String.class.getName());
}
};
final BinaryOperator<String> duplicateHandler = (key1, key2) -> {
throw new IllegalStateException(String.format("Duplicate key %s",
key1));
};
final HashMap<String, String> hashMap = entries.collect(Collectors
.toMap(keyMapper, valueMapper, duplicateHandler, HashMap::new));
System.out.println(hashMap);
如果地图只有字符串到字符串的条目,它将复制它们所有。例如,插入。
map.put("aKey", "aValue");
在评论1处。它将会打印输出。
{aKey=aValue}
这很好。
如果你的映射中至少有一个字符串到非字符串的条目,复制操作将失败。
例如,插入
map.put("aKey", 42);
在评论1中,它会打印出来。
Exception in thread "main" java.lang.ClassCastException: Value '42' of key ' aKey' cannot be cast from type java.lang.Integer to type java.lang.String
at ...
这显示了字符串到非字符串的条目。
我知道这个解决方案并不简单,但它是安全的。