0

是否可以创建一个键是集合(任何类型的集合)的地图?

如果我在最常见的系列上尝试它,我会被告知该系列无法进行比较。

我一直在尝试为自定义集合编写 compareTo 函数,但我很挣扎。

要么我需要编写 compareTo,要么我需要找到一个接受 Maps 接受的集合/集合的预制 Map。

如何将集合用作地图上的键?我查看了堆栈溢出,并多次搜索过这个问题,但我从未找到可靠的解决方案!


我想这样做的原因是我用 Java 编写了一个模拟洗牌的“洗牌”模拟。我希望能够计算出特定手(建模为集合)出现的次数。它看起来像这样:

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

2 回答 2

10

是否可以创建一个键是集合(任何类型的集合)的地图?

是的,这是可能的,但绝对不推荐。如果您的集合发生变化,它的哈希码可能也会发生变化,这可能会导致令人惊讶的行为。

请参阅Map 的 javadoc

注意:如果将可变对象用作映射键,则必须非常小心。如果对象的值以影响等于比较的方式更改,而对象是映射中的键,则不指定映射的行为。


如果我在最常见的系列上尝试它,我会被告知该系列无法进行比较。

键不需要可比较,除非您使用排序映射,即 TreeMap。使用简单的 HashMap 就不会出现问题。


在您编辑之后,我将创建一个新的不可变 Hand 类:

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
}

例如,compareTo如果您想在 a 中使用它TreeSet<Hand, Integer>并按手部力量排序,请实施。

于 2013-06-19T21:40:57.203 回答
2

是的,您可以使用任何集合作为键。如果你想要一个像 TreeMap 这样的 SortedMap,你必须提供一个 Comparator 来确定顺序。但是,如果您使用任何不需要的 HashMap。

Map<List<Integer>, String> map = new HashMap<>();
map.put(Arrays.asList(1,2,3), "one to three");
map.put(Arrays.asList(7,8,9), "seven eat nine");
System.out.println(map);

印刷

{[1, 2, 3]=one to three, [7, 8, 9]=seven eat nine}
于 2013-06-19T21:41:54.257 回答