Nomad
Nomad

Reputation: 1102

java generics with wildcards for map

I am trying to build a map, and it's values can be a list of class person,animals or string, and then I am reading it at the end.

I have the following questions:

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. Is this approach correct, I mean putting these values and read them.
  2. Why not use a Map without parameters, why use generics and generics with wildcards, i did read about it and am still not clear

I would like to try this approach without a pojo. or Is pojo necessary.

Please help, your help will be appreciated.

Thanks

Upvotes: 1

Views: 431

Answers (2)

herman
herman

Reputation: 12305

This approach is not good since the casts are not safe. A cast to List<Person> will not check that all items in the list are of type Person. You would get a ClassCastException when you try to retrieve an element that is not a Person.

You should 1) consider if you really need to put those lists in a Map. 2) if you do, you could copy the lists (if they aren't huge) after getting them from the map:

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

But of course then updates to the list would not be done in the source list.

Upvotes: 0

WhyNotHugo
WhyNotHugo

Reputation: 9924

If you use generics, you don't need to explicitly cast the object you read from the list

Assuming Map<String, Animal> map... then map.get("someKey"); will return an Animal.

The same goes in some of your more complex examples.

The problem arises when you put different types of objects into Maps. It sound like you need a POJO rather than a Map;

class Stuff {

  private List<Person> people;
  private List<Animal> animals;
  private List<String> data;

 // Getters and setters

}

This will be cleaner, and seems to suit your need from what I understand of your question. Just pass Stuff around instead of a Map, which doesn't seem to suit your needs in this case.

Upvotes: 2

Related Questions