【问题标题】:java generics with wildcards for map带有通配符的java泛型映射
【发布时间】:2012-08-11 05:09:25
【问题描述】:

我正在尝试构建一个地图,它的值可以是班级人员、动物或字符串的列表,然后我在最后阅读它。

我有以下问题:

Map<String,List<? extends Object>> someDataMap = 
new LinkedHashMap<String,List<? extends Object>>();

Person p = new Person();
Animals a = new Animals();

List<Person> personList  = p.getPersonList();
List<Animals> animalsList  = a.getAnimalsList();


List<String> someStrings = new ArrayList<String>();

someStrings.add("Employe123");
someStrings.add("Pet-Cat");


// putting lists into map
someDataMap.put("person",personList);
someDataMap.put("animals",animalsList);
someDataMap.put("listsOfData",someStrings);



// now reading the values.


   Map<String,List<? extends Object>> datMap  = 
   (Map<String,List<? extends Object>>)model.get("datMap");

List<Person> dataList = (List<Person>) datMap.get("person");

List<Animals> nodalList = (List<Animals>)datMap.get("animals");

List<String> listsOfData = (List<String>) datMap.get("listsOfData");
  1. 这种方法是否正确,我的意思是放置这些值并阅读它们。
  2. 为什么不使用不带参数的 Map,为什么使用泛型和带通配符的泛型,我确实读过,但仍不清楚

我想在没有 pojo 的情况下尝试这种方法。或者 pojo 有必要吗。

请帮忙,我们将不胜感激。

谢谢

【问题讨论】:

    标签: java generics map wildcard


    【解决方案1】:

    如果使用泛型,则不需要显式转换从列表中读取的对象

    假设Map&lt;String, Animal&gt; map... 那么map.get("someKey"); 将返回Animal

    在您的一些更复杂的示例中也是如此。

    当您将不同类型的对象放入Maps 时,就会出现问题。听起来您需要 POJO 而不是 Map

    class Stuff {
    
      private List<Person> people;
      private List<Animal> animals;
      private List<String> data;
    
     // Getters and setters
    
    }
    

    这会更干净,并且根据我对您问题的理解,似乎符合您的需要。只需传递 Stuff 而不是 Map,在这种情况下,这似乎不适合您的需求。

    【讨论】:

    • 感谢您的回答,我想得到更多的答案。我想看看如何有效地使用 List
    • 泛型Lists 的要点是它们包含相同类型的元素,因此当您从它们get() 值时不必强制转换它们。如果您需要明确区分大小写,则最好考虑一个更好的解决方案。有时,带有三个列表的简单 POJO 可以省去很多麻烦,并产生更简洁的代码。
    【解决方案2】:

    这种方法不好,因为演员表不安全。转换为List&lt;Person&gt; 不会检查列表中的所有项目是否都是Person 类型。当您尝试检索不是Person 的元素时,您会得到ClassCastException

    你应该 1) 考虑是否真的需要将这些列表放入Map。 2)如果你这样做了,你可以在从地图中获取列表后复制列表(如果它们不是很大):

    List<Person> dataList = new ArrayList<Person>(datMap.get("person"));
    

    但当然,列表的更新不会在源列表中完成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-23
      • 1970-01-01
      • 2017-04-28
      • 1970-01-01
      相关资源
      最近更新 更多