转换的最简单/最佳方式是什么?
Map<String, Object>
到
HashMap<String, String>
我使用的API具有返回Map的方法,但如果我不必每次都将Object转换为String,那将会更容易。
此外,这甚至值得做吗? HashMap会比Map更快/更有效吗?
我假设我必须遍历原始Map并将值复制到新的HashMap。
提前致谢!
答案 0 :(得分:9)
您可以像其他人一样使用构造函数:
Map<String, String> newMap = new HashMap(oldMap);
只有当您知道有问题的Object
{/ 1}}时才会有效。
但我应该提一下:
请勿将接口与类混淆。 String
只是界面; 合同,仅包含定义。另一方面,类是接口的具体实现。因此,如果您使用Map
接口或其运行时类型(Map
),则在性能方面没有任何区别。但是,如果您交换实现(例如,HashMap
),它可能会有所不同。
编辑:
以下是EE人员喜欢的详细解决方案(不涉及任何演员/原型警告):
TreeMap
答案 1 :(得分:2)
在原始类型上使用复制构造函数:
HashMap<String, String> hashMap = new HashMap(map);
然而,由于类型系统被忽略,解决方案很难看。
EDIT1:
执行时
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());
}
你得到了类强制转换异常:
Exception in thread "main" java.lang.ClassCastException: java.lang.Object cannot be cast to java.lang.String
当“System.out.println(hashMap.get(”Bla“)。getClass());”时抛出它被执行。
因此,演员阵容实际上已经延迟了。
EDIT2:
您可以使用
来避免复制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>();
// 1
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只有字符串到字符串的条目,它将全部复制它们。 例如。插入
map.put("aKey", "aValue");
评论1.它将打印
{aKey=aValue}
这很好。
如果地图中至少有一个字符串到非字符串条目,则复制将失败。
E.g。插入
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 ...
显示字符串到非字符串的条目。
我知道这个解决方案不是那么简单但是很安全。
答案 2 :(得分:0)
如果你知道键和值的类型(比如<String, String>
),你可以只渲染整个地图:
Map<String, String> newMap = (HashMap<String, String>)oldMap;
如果您需要单独的Map
实例,则可以使用HashMap
的构造函数:
HashMap<String, String> = new HashMap<String, String>((HashMap<String, String>) oldMap);