我得到了如下情况:
Map1 - Map<String, Map<String,List<Vo>>>
Map2 - Map<String, Set<String>
是否可以为上述2个地图设置相同的关键参考,如下所示?
Map<String, Collection<?> mapCommon=new HashMap<String, Collection<?>();
任何人都可以请一些关于如何设置它的想法? 编辑:是同一参考
答案 0 :(得分:1)
您想要做的事情是不可能的,因为Set
和Map
不共享任何常见的实现或超级类Object
。您可以在官方文档中看到它:
你可以做Map<String, Object>
,但我强烈建议你这样做。你怎么知道你的对象是地图还是集合?不可能正确地做到这一点。
在我看来,最好的解决方案是创建一个新类来包装你的两个集合:
public class YourWrapper {
Map<String, Map<String,List<Vo>>> a;
Map<String, Set<String> b;
// getter setter etc...
}
之后你可以创建你的收藏:
Map<String, YourWrapper> myMap = new HashMap<String, YourWrapper>();
答案 1 :(得分:1)
如果我了解您希望将相同的键用于各种不同的类型的值。
为什么没有新的Class
本身由地图,集组成,其实例可以用作值
class MyClass {
private Map<String, List<Vo>> theMap;
private Set<String> theSet;
...
... // have its own getters and setters
}
然后你可以像这样定义你的顶级地图
Map<String, MyClass> myMainMap = new HashMap<String, MyClass>();
或者作为替代方案有一个元组
您可以进一步检查此link,看看是如何完成的。
答案 2 :(得分:1)
你在这里触及两个有趣的元素。
首先 - 地图不属于Collection。 List和Set确实属于,但Map是不同的,即使它与Lists和Sets共享一些共性。
其次 - 将类型混合到一个commonMap中,您尝试的方式是可行的但应该避免,因为它通常不被视为最佳实践。我们正在处理的问题是由类型擦除引起的。一旦编译器编译代码 - 它不传递有关Map或Set持有的泛型类型的任何信息。实际上,Map<String, List<Vo>>
在编译代码中变为原始类型Map<?>
。问题在于回退原始值。如果实例为Map<String, List<Vo>>
或Set<String>
,编译器将不允许您检查实例。
这段代码将失败:
public static void processElement(Object commonMapObjectEitherMapOrSet) {
if (commonMapObjectEitherMapOrSet instanceof Map<String, List<Vo>>) {
//...
}
}
错误:无法对参数化类型执行instanceof检查 地图取代。从而进一步使用表格Map 通用类型信息将在运行时删除
可能的解决方法是忘记泛型并检查实例是否是原始类型集或映射。下面的代码显示了如何检查Object是Map还是Set。
public static void processElement(Object commonMapObjectEitherMapOrSet) {
if (commonMapObjectEitherMapOrSet instanceof Map) {
System.out.println("Got map; but types held in the map are not known due to type-erasure");
// This is where things will get messy as you will get warnings:
Map<String, List<Vo>> map = (Map<String, List<Vo>>) commonMapObjectEitherMapOrSet;
// ...
}
if (commonMapObjectEitherMapOrSet instanceof Set) {
System.out.println("Got set; but types held in the set are not known due to type-erasure");
// This is where things will get messy as you will get warnings:
Set<String> set = (Set<String>) commonMapObjectEitherMapOrSet;
// ...
}
}
上面的问题是将您的commonMap中的值转换回您想要的类型,即。 Map<String, List<Vo>>
和Set<String>
。编译器将无法检查转换是否正确并将发出警告。您可以在技术上用(@SuppressWarnings("unchecked")
注释)抑制警告,但这可能不是最好的事情。
在这个阶段 - 考虑是否创建自己的专门类来管理不同类型是有意义的。 回到原来的问题 - 回答它我发布了将事物映射到公共地图的代码:
package stackoverflow;
import java.util.*;
class Vo {}
public class MultipleRefs {
public static void main(String[] args) {
Map<String, List<Vo>> mapVo = new HashMap<>();
Set<String> set = new HashSet<>();
Map<String, Object> commonMap = new HashMap<>();
//commonMap.put("a", Map)
commonMap.put("mapVoOne", mapVo);
commonMap.put("setOne", set);
commonMap.forEach((key, value) -> processElement(value));
}
public static void processElement(Object commonMapObject) {
if (commonMapObject instanceof Map) {
System.out.println("Got map; but types held in the map are not known due to type-erasure");
// This is where things will get messy:
Map<String, List<Vo>> map = (Map<String, List<Vo>>) commonMapObject;
System.out.println(" processElement prints map: " + map);
}
if (commonMapObject instanceof Set) {
System.out.println("Got set; but types held in the set are not known due to type-erasure");
// This is where things will get messy:
Set<String> set = (Set<String>) commonMapObject;
System.out.println(" processElement prints set: " + set);
}
}
}