patternjavaMinor
Class for Map of Maps
Viewed 0 times
mapsmapclassfor
Problem
After finding myself sometimes needing a map of maps, and as I couldn't find one in existing libs (like Guava), I wrote my own implementation. Do you think this version is okay? Specifically: Is it acceptable that I don't permit empty "inner" maps as content for my "outer" map, hence probably breaking the contract of
```
import java.util.*;
public class MapMap implements Map> {
private Map> underlyingMap = new HashMap>();
public MapMap() {
}
public MapMap(Map> underlyingMap) {
putAll(underlyingMap);
}
@Override
public int size() {
return underlyingMap.size();
}
@Override
public boolean isEmpty() {
return underlyingMap.isEmpty();
}
@Override
public boolean containsKey(Object o) {
return underlyingMap.containsKey(o);
}
@Override
public boolean containsValue(Object o) {
return underlyingMap.containsValue(o);
}
@Override
public Map get(Object o) {
return underlyingMap.get(o);
}
@Override
public Map put(K1 k1, Map k2VMap) {
return (k2VMap == null || k2VMap.isEmpty()) ? null : underlyingMap.put(k1, k2VMap);
}
@Override
public Map remove(Object o) {
return underlyingMap.remove(o);
}
/**
* Puts the contents in a map of maps.
* Note that existing content stored under an outer key will be overwritten by the provided content.
* Note that no empty or null inner maps are stored.
* @param map the content to be added
*/
@Override
public void putAll(Map> map) {
for(Entry> entry : map.entrySet()) {
if (entry.getValue() != null && ! entry.getValue().isEmpty()) {
underlyingMap.put(entry.getKey(), entry.ge
Map? Do I miss useful methods, are some methods superfluous? Should my class implement the Map interface at all, as some methods work counter-intuitive when using this abstraction? Are the names of the additional methods too subtle?```
import java.util.*;
public class MapMap implements Map> {
private Map> underlyingMap = new HashMap>();
public MapMap() {
}
public MapMap(Map> underlyingMap) {
putAll(underlyingMap);
}
@Override
public int size() {
return underlyingMap.size();
}
@Override
public boolean isEmpty() {
return underlyingMap.isEmpty();
}
@Override
public boolean containsKey(Object o) {
return underlyingMap.containsKey(o);
}
@Override
public boolean containsValue(Object o) {
return underlyingMap.containsValue(o);
}
@Override
public Map get(Object o) {
return underlyingMap.get(o);
}
@Override
public Map put(K1 k1, Map k2VMap) {
return (k2VMap == null || k2VMap.isEmpty()) ? null : underlyingMap.put(k1, k2VMap);
}
@Override
public Map remove(Object o) {
return underlyingMap.remove(o);
}
/**
* Puts the contents in a map of maps.
* Note that existing content stored under an outer key will be overwritten by the provided content.
* Note that no empty or null inner maps are stored.
* @param map the content to be added
*/
@Override
public void putAll(Map> map) {
for(Entry> entry : map.entrySet()) {
if (entry.getValue() != null && ! entry.getValue().isEmpty()) {
underlyingMap.put(entry.getKey(), entry.ge
Solution
Rather than making a map of maps (
You could make a generic
Nevertheless, if you use a generic
getting :
or putting :
Map>), I find it often easier to make a map that uses a composite key : Map, V>.You could make a generic
Key class for this, or make a dedicated class on a per case basis since sometimes this key makes sense business-wise : e.g. Buyer - Seller -> Contract.Nevertheless, if you use a generic
Key class (make sure equals() and hashCode() are implemented properly), you could still have use for a variant of your MapMap, that takes individual K1 and K2 objects and combines them into a key behind the scenes. But I think you'll find that a Key class with a static factory method is easy enough to use :getting :
V value = map.get(key(k1, k2));or putting :
map.put(key(k1, k2), value);Code Snippets
V value = map.get(key(k1, k2));map.put(key(k1, k2), value);Context
StackExchange Code Review Q#28252, answer score: 6
Revisions (0)
No revisions yet.