java - 在地图中设置多个值

时间:2016-10-21 15:23:28

标签: java collections hashmap

我得到了如下情况:

Map1 - Map<String, Map<String,List<Vo>>>  
Map2 - Map<String, Set<String>  

是否可以为上述2个地图设置相同的关键参考,如下所示?

Map<String, Collection<?>  mapCommon=new HashMap<String, Collection<?>();  

任何人都可以请一些关于如何设置它的想法? 编辑:是同一参考

3 个答案:

答案 0 :(得分:1)

您想要做的事情是不可能的,因为SetMap不共享任何常见的实现或超级类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);
        }
    }
}