我使用的API有返回的方法Map<String, Object>
,但我知道Object
的是String
的在这种情况下,所以我想它作为一个Map<String, String>
.
但由于某些原因,我不能只投它,爪哇说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)));
}
Run Code Online (Sandbox Code Playgroud)
作为一种解决方法,但有更简单的方法吗?
Jon*_*eet 11
好吧,你无法安全地将其转换为a,Map<String, String>
因为即使你知道你只有字符串作为值,编译器也不会.这就像期待:
Object x = "foo";
String y = x;
Run Code Online (Sandbox Code Playgroud)
工作 - 它没有; 你需要明确施放.
同样,如果你通过,你也可以在这里明确地投射Object
:
Map<String, Object> x = ...;
Map<String, String> y = (Map<String, String>) (Object) x;
Run Code Online (Sandbox Code Playgroud)
现在你会得到一个警告,说它是一个未经检查的强制转换,因为与之前的"对象到字符串" 强制转换不同,没有执行时检查它是否真的有效.类型擦除意味着地图并不真正知道其键/值类型.因此,最终只检查在获取元素时是否完成:
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"));
}
}
Run Code Online (Sandbox Code Playgroud)
因此,如果你真的想避免创建一个新的地图,这个"强制转换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;
}
Run Code Online (Sandbox Code Playgroud)
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()));
}
Run Code Online (Sandbox Code Playgroud)