Generics: How to get values of a Map without casting

Viewed 1096

I have an abstract class named BaseCode and 2 concrete classes named Location and Department:

public abstract class BaseCode {
   private Integer id;
   ...
   public Integer getId() { return id; }
   public void setId(Integer id) { this.id = id; }
   ...
}

public class Location extends BaseCode {
   ...
}

public class Department extends BaseCode {
   ...
}

I have an abstract class named BaseCodeCache and 2 concrete classes named LocationCache and DepartmentCache. LocationCache and DepartmentCache will be using Singleton.

public abstract class BaseCodeCache {
   ...
}

public class LocationCache extends BaseCodeCache {
   ...
}

public class DepartmentCache extends BaseCodeCache {
   ...
}

  1. In BaseCodeCache, I want to have a java.util.Map whose value can be any type of BaseCode i.e. Location objects or Department objects.
    In LocationCache, I want the java.util.Map to store Location objects.
    In DepartmentCache, I want the java.util.Map to store Department objects.

To accomplish this, I put this code in BaseCodeCache:

private Map<Integer, BaseCode> idMap = new HashMap<Integer, BaseCode>();

  1. I want to have a method to store a value in the java.util.Map.

To accomplish this, I put this code in BaseCodeCache:

public void add(BaseCode baseCode) {
   if (baseCode != null) {
      idMap.put(baseCode.getId(), baseCode);
   }
}

This is how I would use it for Location:

Location location = new Location(); ...
LocationCache.getInstance().add(location);

This is how I would use it for Department:

Department department = new Department(); ...
DepartmentCache.getInstance().add(department);

  1. I want to have a method to get all values in the java.util.Map as a java.util.List.
    In LocationCache this method should return List<Location>.
    In DepartmentCache this method should return List<Department>.

Thats where I am stuck. I want to create this method in BaseCodeCache but when this method is called via LocationCache then it returns List<Location> and when this same method is called via DepartmentCache then it returns List<Department>. Is it possible?

I put this code in BaseCodeCache:

public List<BaseCode> getList() {
   return new ArrayList<BaseCode>(idMap.values());
}

But the above code returns List<BaseCode>. When I would call it this way:

List<Location> allLocations = LocationCache.getInstance().getList();

Then java will not let it compile and give this error message:

Type mismatch: cannot convert from List<BaseCode> to List<Location>

I can get it fixed by getting List<BaseCode> and then converting it to List<Location> by looping but thats does not look right.

Can it be done?

1 Answers
Related