是否可以创建一个密钥是Collection(任何类型的集合)的地图?
如果我在大多数常见的收藏中尝试,我会被告知收藏品不能用于比较。
我一直在尝试为自定义集合编写compareTo函数,但我很挣扎。
要么我需要编写compareTo,要么我需要找到一个接受地图接受的集合/集合的预制地图。
如何将集合用作地图上的键?我已经查看了Stack溢出,我已经多次搜索过这个问题,但我从来没有找到一个可靠的解决方案!
我想这样做的原因是我在Java中编写了一个模拟卡片洗牌的“随机”模拟。我希望能够计算特定手(建模为集合)出现的次数。它看起来像这样:
H4,C3,D2: 8
H9,D6,S11: 10
......
答案 0 :(得分:10)
是否可以创建一个密钥是Collection(任何类型的集合)的地图?
是的,这是可能的,但绝对不推荐。如果您的集合发生更改,则其哈希码可能也会发生变化,这可能会导致令人惊讶的行为。
请参阅Map's 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
,如果您想在TreeSet<Hand, Integer>
中使用它并按手工强度排序,例如。
答案 1 :(得分: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}