如何以最干净的方式将Map<Object,Object>
投射到Map<String,String>
?
有没有办法在不迭代地图的情况下做到这一点?
由于
答案 0 :(得分:11)
实际答案是:
Map<Object,Object> valueMap = ...;
@SuppressWarnings("unchecked")
Map<String,String> targetMap = (Map)valueMap;
答案 1 :(得分:9)
我认为解释为什么简单的解决方案不起作用以及为什么你永远不应该使用它是个好主意。
假设您可以将List<Object>
转换为List<String>
(这同样适用于Map,只是一个更简单的界面)。您希望从以下代码中发生什么:
List<Object> m = Something;
m.add("Looks good.");
m.add(42);
List<String> s = (List<String>)m; // uhuh, no we don't want that.
String myString = s.get(1); // huh exception here.
现在你可以使用波希米亚人/克里斯解决方案破解它,但你基本上破坏了Java的类型系统。 请勿这样做。您不希望List<String>
包含整数!稍后进行有趣的调试 - 循环遍历所有变量的附加代码将避免许多令人头痛的问题,并且几乎不会出现性能问题。
如果有理由将Map声明为使用Object而不是String,则可能会向其添加任何对象 - 通常您应该能够通过更好的泛型来避免这种情况。
答案 2 :(得分:1)
在Chris J's answer的基础上,这是他的“黑客”代码,显示它有效:
public static void main(String[] args) {
Map<Object, Object> valueMap = new HashMap<Object, Object>();
valueMap.put("foo", "bar");
@SuppressWarnings("unchecked")
Map<String, String> targetMap = (Map<String, String>) ((Object) valueMap); // hack alert!
for (Map.Entry<String, String> entry : targetMap.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key + "=" + value); // prints foo=bar :)
}
}
哇!没有运行时异常:)
答案 3 :(得分:0)
如果您想要清洁的东西,则必须“深入”转换!键和值。
使用Java 8流,只需几行:
static public Map<String, String> toStringString(Map<? extends Object, ? extends Object> map) {
return map
.entrySet()
.stream()
.collect(Collectors.toMap(
e -> e.getKey().toString(),
e -> e.getValue().toString()
));
}
答案 4 :(得分:0)
public Map<String, String> castOnlyStringValues(final Map<String, Object> map) {
return map.entrySet().stream()
.filter(x -> String.class.isAssignableFrom(x.getValue().getClass()))
.map(x -> (Entry<?, ?>) x).map(x -> (Entry<String, String>) x)
.collect(toMap(Entry::getKey, Entry::getValue));
}