Search code examples
javacollectionsdictionarycomparable

Creating a map with a collection as the Key?


Is it possible to create a map where the key is a Collection (any sort of collection)?

If I try it on most common collections I'm told the collection can't be cast to comparable.

I've been trying to write a compareTo function for a custom collection, but I am struggling.

Either I need to write the compareTo, or I need to find a premade Map that accepts collections/Collection accepted by Maps.

How can I use a collection as a key on a map? I've looked over Stack overflow and I've googled this problem several times, but I've never found a solid solution!


The reason I want to do this is that I've written a 'shuffle' simulation in Java that mimic card shuffling. I want to be able to count up the number of times a specific hand (modeled as a collection) comes up. It would look something like this:

   H4,C3,D2: 8  
   H9,D6,S11: 10  
   ......

Solution

  • Is it possible to create a map where the key is a Collection (any sort of collection)?

    Yes it is possible, but definitely not recommended. If your collection changes, it is likely that its hashcode will also change and that can lead to surprising behaviour.

    See Map's javadoc:

    Note: great care must be exercised if mutable objects are used as map keys. The behavior of a map is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is a key in the map.


    If I try it on most common collections I'm told the collection can't be cast to comparable.

    The key does not need to be comparable, unless you use a sorted map, i.e. TreeMap. Use a simple HashMap and you won't have the issue.


    Following your edit, I would create a new immutable Hand class:

    class Hand implements Comparable<Hand> {
        private final List<Card> cards;
        Hand(Card c1, Card c2, Card c3) {
            cards = Collections.unmodifiableList(Arrays.asList(c1, c2, c3));
        }
        //getters, no setters
        //implement compareTo
    }
    

    and implement compareTo if you want to use it in a TreeSet<Hand, Integer> and sort by hand strength for example.