HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Class for Map of Maps

Submitted by: @import:stackexchange-codereview··
0
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 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 (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.