Multiple Keys to Single Value Map Java

后端 未结 4 1009
忘了有多久
忘了有多久 2020-12-03 10:47

I think my question is similar to this one: How to implement a Map with multiple keys? but with an important difference. In that question (if my understanding of it is corre

相关标签:
4条回答
  • 2020-12-03 10:58

    Apache Commons Collections has MultiKey.

    import org.apache.commons.collections4.keyvalue.MultiKey;
    
    Map<MultiKey, ValueType> myMap = new HashMap<MultiKey, ValueType>();
    myMap.put(new MultiKey(key1, key2), value);
    
    myMap.get(new MultiKey(key1, key2));
    

    It has the benefit of creating N-dimensional arrays from a Map.

    0 讨论(0)
  • 2020-12-03 10:58

    It sounds to me like you're looking for a nested HashMap. This could work, but my gut says implementing such a monster would be a terrible idea, both performance-wise and sanity-wise.

    How you could initialize it:

        HashMap<Key1, HashMap<Key2, Value>> nestedHashMap = new HashMap<Key1, HashMap<Key2, Value>>();
    

    Adding values:

        Key1 first;
        Key2 second;
        Value data;
        HashMap<Key2, Value> tempMap = new HashMap<Key2, Value>();
        tempMap.put(second, data);
        nestedHashMap.put(first, tempMap);
    

    Getting data back out:

        Key1 first;
        Key2 second;
        Value data;
        data = nestedHashMap.get(first).get(second);
    

    Disclaimer: This code hasn't been tested, it just came off the top of my head.

    0 讨论(0)
  • 2020-12-03 11:11

    The Table data structure in Guava seems to meet you requirement of refering to a value by a pair of objects.

    0 讨论(0)
  • 2020-12-03 11:14

    I hope this answer won't be seen as a rant, but as far as I could understand, you want to use a library for something that you can achieve in a trivial way using a jdk out of the box.

    Anyway, you mentioned that you want to access elements using a pair of objects. You could create a class that will hold the keys, such as

    public class Pair {
      // string represntation of an object
      private final String x; 
      private final String y;
    
      // ctor, getters...
    
      public int hashcode() {...}
      public boolean equals(Object other) {...}
    }
    

    The hashcode method will generate the hashcode for all comprising elements (in this case, two, xand y in your case, but can be easily extended to support an arbitrary number of elements), and two keys will be the same if they have the same values for xand y. If your pair elements are not simple strings, it is trivial to derive a string representation of almost any object (provide a decent implementation of the toString method, for instance).

    The idea is to have a unique string representation for each element in the pair.

    Of course, generating solid hashcodes is not trivial, so an excellent option isto use Strings. To generate a hashcode, you would simply append the string representations of your pair objects:

    public int hashcode() {
      return ('x' + x + ":y" + y).hashcode();
    }
    

    Be sure to provide some separator. Otherwise, for values such as x=ab, y=b, and x=a, y=bb, you'll get the same hashcode, even if the objects are completely different.

    And equality is as trivial as inspecting the value of the elements in the pair:

    public boolean equals(Object other) {
      // if other is not null and is an instance of Pair
      final Pair otherPair = (Pair)other;
      return this.x.equals(otherPair.x) && this.y.equals(otherPair.y);
    }
    

    So, now you could use your Pairclass in a map, such as in:

    final Map<Pair, Whatever> map = new Hashmap<Pair, Whatever>();
    // ...
    

    Basicaly, a hashmap works by using the hashcode of the keys to determine in which bucket the value should be allocated. If two keys have the same hashcode, then the equals method will be used to determine if a collision just occurred, or if it's just the same key.

    If you want to use your Pair class in a TreeMap, you would have to implement the compareTo method, or provide your own Comparator when instantiating such a map. TreeMap implementations rely on the result of the compareTo method to determine where a value should be allocated.

    0 讨论(0)
提交回复
热议问题