MultiKey Map

Java Map interface doesn’t provide possibility to have multiple keys for single entry. Let’s see what are the possible workarounds.

1. Implement our own MultiKey object

public class MultiKey {
    private String key1;
    private String key2;
    String[] keys;

    public MultiKey(String... keys) {
        this.keys = keys;
    }

    @Override
    public int hashCode() {
        int i = 1;
        StringBuffer keysChain = new StringBuffer();
        for (String key : keys) {
            keysChain.append("key" + i + key + "|");
            i++;
        }
        return keysChain.toString().hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null || !(obj instanceof MultiKey)) {
            return false;
        }
        MultiKey multiKey = (MultiKey) obj;
        return Arrays.equals(multiKey.keys, this.keys);
    }
}

The important point here is to overright equals() and hashCode() methods.
The usage will be the following:

Map<MultiKey, String> nameToLocation = new HashMap<>();
nameToLocation.put(new MultiKey("Tom","Jones"), "USA");
nameToLocation.put(new MultiKey("Jose","Gonzalez", "Andreas"), "Spain");
nameToLocation.put(new MultiKey("Johan"), "Germany");
[addToAppearHere]

2. Map of Maps solution:

Map<String, Map<String, String>> multiMap = new HashMap<>();
Map<String, String> nestedMap = new HashMap<>();
nestedMap.put("Jones", "USA");
multiMap.put("Tom", nestedMap);

multiMap.get("Tom").get("Jones")

// Output: "USA"

3. Guava Table
Guava library provides Table data structure which under the hood uses Map of Maps solution. This is only when we have double keys.

Table<String, String, String> table = HashBasedTable.create();
table.put("Tom", "Jones", "USA");

// Output: "USA"

4. Apache Commons MultiKeyMap

With MultiKeyMap we can have not only two but more keys

MultiKeyMap multiKeyMap = new MultiKeyMap();
nameToLocation.put(new MultiKey("Jose","Gonzalez", "Andreas"), "Spain");

// Output: "Spain"