我使用的API有一个返回Map<String, Object>
的方法,但我知道Object
在这种情况下是String
,所以我希望它为Map<String, String>
。
但出于某种原因,我无法投出它,Java说Map<String, Object>
由于某种原因无法投放到Map<String, String>
。
我用过:
Map<String, Object> tempMap = someApiMethodReturningAMap();
Map<String, String> map = new HashMap<String, String>();
for (String i : tempMap.keySet()) {
map.put(i, String.valueOf(tempMap.get(i)));
}
作为一种解决方法,但有更简单的方法吗?
答案 0 :(得分:11)
嗯,你不能安全地将其转换为Map<String, String>
,因为即使你知道你只有字符串作为值,编译器也不会“T。这就像期待:
Object x = "foo";
String y = x;
工作 - 它没有;你需要明确地施放。
同样,如果您通过Object
:
Map<String, Object> x = ...;
Map<String, String> y = (Map<String, String>) (Object) x;
现在你会得到一个警告,说它是一个未经检查的强制转换,因为与之前的“对象到字符串”强制转换不同,没有执行时检查它是否真的有效。类型擦除意味着地图并不真正知道其键/值类型。因此,您最终只能在获取元素时进行检查:
import java.util.*;
class Test {
public static void main(String[] args) {
Map<String, Object> x = new HashMap<>();
x.put("foo", "bar");
x.put("number", 0);
Map<String, String> y = (Map<String, String>) (Object) x;
// This is fine
System.out.println(y.get("foo"));
// This goes bang! It's trying to cast an Integer to a String
System.out.println(y.get("number"));
}
}
因此,如果您真的想避免创建新地图,那么“通过Object
投射”将会奏效 - 但这远非理想。
您的方法更安全,但您可以通过避免查找来提高效率:
public static Map<String, String> copyToStringValueMap(
Map<String, Object> input) {
Map<String, String> ret = new HashMap<>();
for (Map.Entry<String, Object> entry : input.entrySet()) {
ret.put(entry.getKey(), (String) entry.getValue());
}
return ret;
}
答案 1 :(得分:2)
Java 8解决方案:
private Map<String, String> stringifyValues(Map<String, Object> variables) {
return variables.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> (String) e.getValue()));
}
答案 2 :(得分:0)
这里有很好的解决方案,但我想添加另一个考虑处理null
值的解决方案:
Map<String,Object> map = new HashMap<>();
Map<String,String> stringifiedMap = map.entrySet().stream()
.filter(m -> m.getKey() != null && m.getValue() !=null)
.collect(Collectors.toMap(Map.Entry::getKey, e -> (String)e.getValue()));