Map with inner map

Consider a small cache (in Java 1.4) - only as example:

publicinterface IDatabaseEnumeration{

publicabstract String getCode();

}

publicclass Cache{

privatefinal Map cachedObjects =new HashMap();

publicvoid addCachedObjects(Collection objects, Class objectClass){

// transfer coll into map

Map map =new HashMap();

for (Iterator it = coll.iterator(); it.hasMoreElements(); ){

IDatabaseEnumeration element = (IDatabaseEnumeration)it.next();

map.put(element.getCode()), element);

cachedObjects.put(objectClass, map);

}

}

public IDatabaseEnumeration findCachedObject(Class objectClass, String code){

Map map = (Map) cachedObjects.get(objectClass);

return map.get(code);

}

}

Description: have a map and store there pairs: key = collection object class, value = collection of objects. Object must be a implementation of IDatabaseEnumeration interface. When storing collection, transfer all data into a new inner map using object code. When looking for some cached object, give a class of this object and a code. Via class (used as key in map) will find a proper collection map and then return an object using given code.

How this cache can be written using generics? I spent several hours thinking and rewriting this small example into Java5/6, but with no success (without warnings and explicit casting). I thing, that it is impossible to write it completely type safe, because the main map (cachedObjects) can't know the relationship between it's keys and collection types.

Maybe the example is completely bad and should be changed to be rewritable into generics :-)

[2503 byte] By [kingmaplea] at [2007-11-26 17:15:04]
# 1

I'm not sure what you are really after. This is what I could gain from applying generics to your code (after fixing minor syntax errors):public interface IDatabaseEnumeration {

public abstract String getCode();

}

public class Cache {

private final Map<Class><?>, Map<String, IDatabaseEnumeration>> cachedObjects = new HashMap<Class><?>, Map<String, IDatabaseEnumeration>>();

public void addCachedObjects(Collection<? extends IDatabaseEnumeration> coll, Class<?> objectClass) {

// transfer coll into map

Map<String, IDatabaseEnumeration> map;

if (cachedObjects.containsKey(objectClass)) {

map = cachedObjects.get(objectClass);

} else {

map = new HashMap<String, IDatabaseEnumeration>();

cachedObjects.put(objectClass, map);

}

for (IDatabaseEnumeration element : coll) {

map.put(element.getCode(), element);

}

}

public IDatabaseEnumeration findCachedObject(Class<?> objectClass, String code) {

Map<String, IDatabaseEnumeration> map = cachedObjects.get(objectClass);

return map.get(code);

}

}

I am not sure, what you mean by "the main map (cachedObjects) can't know the relationship between it's keys and collection types", though.

stefan.schulza at 2007-7-8 23:43:03 > top of Java-index,Core,Core APIs...
# 2

> I am not sure, what you mean by "the main map

> (cachedObjects) can't know the relationship between

> it's keys and collection types", though.

Maybe he would like to ensure type-safety with regards to the Class object as a key and the matching IDatabaseEnumeration objects as values. One might enhance your code like this:

interface IDatabaseEnumeration {

public abstract String getCode();

}

public class Cache {

private final Map<Class><?>, Map<String, IDatabaseEnumeration>> cachedObjects = new HashMap<Class><?>, Map<String, IDatabaseEnumeration>>();

public <T extends IDatabaseEnumeration> void addCachedObjects(Collection<T> coll, Class<T> objectClass) {

// transfer coll into map

Map<String, IDatabaseEnumeration> map;

if (cachedObjects.containsKey(objectClass)) {

map = cachedObjects.get(objectClass);

} else {

map = new HashMap<String, IDatabaseEnumeration>();

cachedObjects.put(objectClass, map);

}

for (IDatabaseEnumeration element : coll) {

map.put(element.getCode(), element);

}

}

public <T extends IDatabaseEnumeration> T findCachedObject(Class<T> objectClass, String code) {

Map<String, IDatabaseEnumeration> map = cachedObjects.get(objectClass);

return objectClass.cast(map.get(code));

}

}

McNeppa at 2007-7-8 23:43:03 > top of Java-index,Core,Core APIs...