Search code examples
javacollectionsmultikey

Map with multiple keys


I am trying to implement a map like

Map<<key1, key2>, List<value>>

Map should contain 2 keys and corresponding value would be a list. I want to add records in same list if alteast one key value is equal For example consider following records

R1[key1, key2]
R2[key1, null/empty] - Key1 is equal
R3[null/empty, key2] - Key2 is equal
R4[key1, key2] - Key1 and Key2 both are equal.

all should be inserted in same list like

Key = <Key1,Key2> 
Value = <R1, R2, R3, R4>

I cant use Guava table or commons MulitKeyMap (dont want include whole library just for this) .

I tried to implement a class (which I can use as a key) which will have both key1 and key2 as attribute but implementing a effective hashcode which don't consider key1 and key2 seems bit (or may be a lot) tricky

public class Key {
    private int key1;
    private int key2;

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        // Cant include key1 and key2 in hashcode 
       /* result = prime * result + key1;
        result = prime * result + key2;*/
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Key other = (Key) obj;
        if(key2 and other.key2 both not blank/null){ // pseudo code
        if (key2 == other.key2)
            return true;
        }
        if(key1 and other.key1 both not blank/null){ //pseudo code
        if (key1 == other.key1)
            return true;
        }
        return true;
    }

}

It will work if I use the same hashcode for all but it will impact the performance as I have thousands of records.


EDIT :
I cant use nested Maps like

Map<key1, Map< key2, List<value>>>

As some records might have only one key.

  R1[key1, key2]     - Have both keys
  R2[key1, null/empty] - Key1 is equal
  R3[null/empty, key2] - Key1 is missing and key2 is equal

Here R3 dont have key1 and hence cant be inserted in same location as R1 and R2


EDIT 2 :

I also wish to maintain the intertion order.


Solution

  • Use a TreeMap instead, this way you can make use a custom comparator for your CustomKey class instead of a Hashcode.

    TreeMap<CustomKey, List<value>> map = new TreeMap<CustomKey, List<value>>(myComparator);
    

    eta: instead of creating a comparator class you can make the CustomKey class implement Comparable