Java 创建以集合为键的地图?
是否可以创建一个映射,其中键是一个集合或任何类型的集合 如果我在最常见的收藏上试用,我会被告知该收藏无法与之媲美 我一直在尝试为自定义集合编写一个compareTo函数,但我正在努力 要么我需要将compareTo写入,要么我需要找到一个接受集合/由映射接受的集合的预制映射 如何将集合用作地图上的键?我已经查看了堆栈溢出,并在谷歌上搜索了好几次这个问题,但我从来没有找到一个可靠的解决方案 我想这样做的原因是,我已经用Java编写了一个模拟洗牌的“洗牌”模拟。我希望能够计算出一个特定的手作为一个集合出现的次数。它看起来像这样:Java 创建以集合为键的地图?,java,collections,map,comparable,Java,Collections,Map,Comparable,是否可以创建一个映射,其中键是一个集合或任何类型的集合 如果我在最常见的收藏上试用,我会被告知该收藏无法与之媲美 我一直在尝试为自定义集合编写一个compareTo函数,但我正在努力 要么我需要将compareTo写入,要么我需要找到一个接受集合/由映射接受的集合的预制映射 如何将集合用作地图上的键?我已经查看了堆栈溢出,并在谷歌上搜索了好几次这个问题,但我从来没有找到一个可靠的解决方案 我想这样做的原因是,我已经用Java编写了一个模拟洗牌的“洗牌”模拟。我希望能够计算出一个特定的手作为一个集
H4,C3,D2: 8
H9,D6,S11: 10
......
是否可以创建一个映射,其中键是一个集合或任何类型的集合
是的,这是可能的,但绝对不推荐。如果您的集合发生更改,则其哈希代码可能也会更改,这可能会导致令人惊讶的行为
见:
注意:如果将可变对象用作贴图键,则必须非常小心。如果对象是贴图中的关键点时,对象的值以影响相等比较的方式更改,则不会指定贴图的行为
如果我在最常见的收藏上试用,我会被告知该收藏无法与之媲美
该键不需要具有可比性,除非使用已排序的映射,即TreeMap。使用一个简单的HashMap,你就不会有问题了
编辑之后,我将创建一个新的不可变手类:
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并按手动强度排序(例如),请执行compareTo。是的,您可以使用任何集合作为键。如果你想要一个像树形图这样的分类图,你必须提供一个比较器来确定顺序。但是,如果您使用任何类型的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);
首先,为什么要将集合用作键?映射背后的整个概念是不可变键,集合直接违反了这个概念。这不是一个好主意,除非集合是只读的,否则它们很可能会更改,结果是改变了equals和hashCode的行为,在检查键是否已存在或检索映射中的键时,很可能会产生很难预测的结果。您可以使用ArrayList的toString方法将字符串用作键,也可以使用自定义格式化程序为您创建字符串,每次附加到字符串时,都需要删除旧字符串的条目。@user962029我确信在更改卡和卡组类之前我已经尝试过了,但现在我已经更改了它。如果没有编写compareTo方法,我就不会尝试它。我一直在努力解决这一问题。同意必须小心确保密钥在保存时不会更改用作密钥。使用不可修改的集合作为密钥可以缓解此问题吗?@tieTYT您只需确保不修改密钥即可。不可修改的集合将强制执行该操作。@assylas从技术上讲,它需要不可修改且具有副本。如果仅使用unmodifiableCollectioncoll,则仍可以修改基础集合:在最后一次编辑中,我认为还实现equals和hashCode是非常明智的,可能只需返回cards字段的equals和hashCode。。。
{[1, 2, 3]=one to three, [7, 8, 9]=seven eat nine}