You could use just a single Map<String, KeyOrValue>
where the value could be a marker interface with two implementations
interface KeyOrValue {}
class Key implements KeyOrValue {
private String key;
}
class Value implements KeyOrValue {
private List<String> values;
}
You could then just create a lookup method which recursivly calls itself and then returns the value once it has reached the end:
private final Map<String, KeyOrValue> map = ...
public List<String> getValues(String key) {
KeyOrValue keyOrValue = map.get(key);
if(keyOrValue instanceof Key) {
// is a key, so use recursion to get the value
key = ((Key) keyOrValue).key;
return getValues(key);
} else if(keyOrValue instanceof Value) {
// is a value, so just return the value it holds
return ((Value) keyOrValue).values;
} else {
// no mapping was found for "key"
return null;
}
}
You could do the same without recursion too:
public List<String> getValues(String key) {
KeyOrValue keyOrValue;
List<String> values = null;
do {
keyOrValue = map.get(key);
if(keyOrValue instanceof Key) {
// is a key, so iterate further
key = ((Key) keyOrValue).key;
} else if(keyOrValue instanceof Value) {
// is a value, so get the values out and set the key to null to break the loop
values = ((Value) keyOrValue).values;
key = null;
}
} while(key != null);
// return the values, may be null due to nothing being found
return values;
}
The marker interface is not really needed though, you can get the same outcome if you just use Map<String, Object>
where the value could either be a String
or a List<String>
and then the instanceof
checks would have to be adapted too, but I like the approach the way with an interface
more