我有一个Map<?, String>
类型的字典。密钥类型在运行时未知。我仍然可以用一个字符串调用get()
,如果存在这样的元素,我就能正确获取存储的对象。
现在我修改了那个对象,并想把它放回字典中。理想情况下,我想做这样的事情:
Map<String, String> hat = new HashMap<>();
hat.put("bunny", "rabbit");
Map<?, String> magicHat = hat;
String trick = magicHat.get("bunny");
if (trick != null) {
trick = "jack".concat(trick);
magicHat.put("bunny", trick);
}
但是,可以理解的是,调用magicHat.put("bunny", trick);
会出现以下编译错误:incompatible types: String cannot be converted to CAP#1
。
解决它的一种方法是使用流(或迭代)来获取地图的条目,然后使用该条目来修改值:
Map.Entry<?, String> entry = magicHat.entrySet()
.stream()
.filter(e -> "bunny".equals(e.getKey()))
.findFirst()
.orElse(null);
if (entry != null) {
String trick = "jack".concat(entry.getValue());
entry.setValue(trick);
}
在现实生活中,我受Java 6的束缚,无法承受流的舒适感。迭代所有条目似乎效率低下。
是否有一种优雅的方式可以随机访问地图中的条目,具有密钥?
感谢您的见解。
答案 0 :(得分:2)
您应该将键类型设置为Object而不是通配符(?)。这样,您不必知道类型。但是,您应该确保永远不会在地图中存储不同类型的键。
Map<String, String> hat = new HashMap<>();
hat.put("bunny", "rabbit");
Map<Object, String> magicHat = new HashMap<>();
hat.forEach(magicHat::put); // Edit: Added this
String trick = magicHat.get("bunny"); // String extends Object
if (trick != null) {
trick = "old".concat(trick);
magicHat.put("bunny", trick);
}
在大多数情况下,此问题的解决方案是使用泛型类型变量。这样,您仍然具有类型安全性,但在编译期间不必知道密钥类型。