Creating a hashmap with a double key

13,098

Solution 1

If you can use a library, take a look at the Table interface of Guava. It associates a row and a column with a value. The row and columns may be your first and second keys. Also you can have searches by row or by column.

One of the implementations of this interface is hash based.

Solution 2

You have to create a key class (equality is treated as Point):

public class Key {

    int field1;
    int field2;

    public boolean equals(Object o) {
        if (o == null || !(o instanceof Key)) return false;
        Key other = (Key) o;
        return field1 == other.field1 && field2 == other.field2;
    }

    public int hashCode() {
        return field1*field2; // doesn't matter if some keys have same hash code
    }

}

For selecting keys with one specific value in the first field:

public List<Key> getKeysWithField1EqualsTo(int value) {
    List<Key> result = new ArrayList<>();
    for (Key k: map.keySet()) {
        if (k.field1 == value) result.add(k);
    }
    return result;
}

Solution 3

Since this is rather specific to your problem at hand, you will very likely need to develop your own collection. I would wrap two MultiMaps from Apache Commons into my own collection class that deals with updates of both multi-maps at the same time, and use my class to perform inserts and queries.

Solution 4

Write a simple class that is able to contain two values (the keys) and override equals(..) and hashCode() for equality checks used by the map. Use this simple class as the key for the map.

Here you can find a hashmap compatible pair class (2nd answer):

What is the equivalent of the C++ Pair<L,R> in Java?

Solution 5

Since a HashMap can only sort on one hash for every object, you will never be able to select the distinct lists 'out of the box'. What I would suggest is using a Tuple with two keys, and then iterate over the HashMap and select only those elements that have tuple.key1=X.

Share:
13,098
Danielle
Author by

Danielle

Updated on June 07, 2022

Comments

  • Danielle
    Danielle almost 2 years

    I am looking for an appropriate data structure for my problem. I would like to be able to select node objects as efficiently as possible using two keys. Insertion and deletion also needs to be efficient. Basically every node object has a pair of two keys. The pairs are unique but the individual keys are not. I need to be able to select a group of nodes that have a particular value for one of the two keys.

    Example:

    Node1 has keys a1 and b1

    Node2 has keys a1 and b2

    Node3 has keys a2 and b2

    I would like to for example be able to select the node with the key a1,b1 but also all nodes that have b2 as key2.

    I could of course make two HashMaps (one for each key) but this is kind of an ugly solution because when I add or remove something I would have to do it in both maps. Since there will be a lot of adding and removing going on I would prefer to do this in one go. Does anyone have any ideas about how to do this?

    Obviously having a single key that merges the two keys together does not solve the problem because I also need to be able to search for a single key without having to search through the whole map. That wouldn't be very efficient. The problem is an efficiency problem. I could just search every entry in the map for a particular key but instead I would like to use a hash so that I can select multiple node objects using either one of the two keys instantly.

    I am not looking for something like the MultiKeyMap because in this data-structure the first key always stays the same, you can only add keys instead of replacing the first key with a different key. I want to be able to switch between the first and the second key.

    I do and do not want to store multiple objects with the same key. If you look at the example you can see that the two keys together are always unique. This can be seen as a single key therefore I would not store multiple objects under the same key. But if you look at the individual keys, these are not unique therefore I do want to store multiple objects referenced by the individual keys.

  • Sergey Kalinichenko
    Sergey Kalinichenko over 12 years
    This does not solve the OP's problem (he needs to search on one key, and get multiple values).