Java 我可以用hashset作为HashMap中的键吗?如果没有,建议一个替代方案

Java 我可以用hashset作为HashMap中的键吗?如果没有,建议一个替代方案,java,hashmap,set,hashset,Java,Hashmap,Set,Hashset,编辑:现在正确地解释了问题 我有一个hashmap,我想在其中存储一起看到的单词集(key)和它们一起看到的行(value)。这就是我提出的结构: HashMap<HashSet<String>, HashSet<Integer>> hm= ... 我只需将新行添加到该键的对应值中,如果没有,则在hashmap中创建一个新条目并处理它 我决不更改现有密钥。我只在hasmmap中更新它们相应的值 在读取文件的最后,我的hashmap应该是这样的 [苹果,香蕉]

编辑:现在正确地解释了问题

我有一个hashmap,我想在其中存储一起看到的单词集(key)和它们一起看到的行(value)。这就是我提出的结构:

HashMap<HashSet<String>, HashSet<Integer>> hm= ...
我只需将新行添加到该键的对应值中,如果没有,则在hashmap中创建一个新条目并处理它

我决不更改现有密钥。我只在hasmmap中更新它们相应的值

在读取文件的最后,我的hashmap应该是这样的

[苹果,香蕉]=[1,2]

[桃子,海象]=[3,4]

问题是

if(hashmap.containsKey(hashset))
这段代码并不总是检测现有的密钥。为什么会这样?这种结构是不允许的吗


谢谢

您可以,但是一旦您添加了一个
HashSet
作为
HashMap
的键,您就不应该再修改它,因为
HashSet.hashCode()
可能会更改,您将再也找不到您的
HashSet
。换句话说,如果您正在执行类似的操作,请确保您的键是不可变的
哈希集
(另请参见)


另一种方法是将与from一起使用,这应该可以工作,但您需要注意键的可变性。如果您更改其中一个键的内容,其哈希代码将更改,并且您的映射将开始执行奇怪的操作。从javadoc获取:

注意:如果使用可变对象作为映射,则必须非常小心 钥匙。如果对象的值 以影响相等比较的方式更改,而 对象是地图中的一个关键点。这项禁令的一个特例是: 不允许贴图将自身包含为键。当它 允许贴图将自身包含为值,请格外小心 建议:equals和hashCode方法不再定义良好 在这样的地图上


要避免这种情况,请在创建时立即使用集合.unmodifiableSet()包装键,或者仅使用番石榴。

您遇到的问题可以通过@Lukas ans@Matt得到很好的解释。
我认为您可以使用扩展或使用装饰器模式来创建一个
Hashset
,它以独立于内容的方式覆盖
等于
hashCode


通过这种方式,您可以避免仅针对特定问题引入对第三方JAR的依赖性

第5行是否也会映射到
peach,walrus
?芒果怎么样?@pcalcao是的。它的行为很奇怪。有时它检测到集合存在,有时不存在。“我只是想验证HashMap是否可以处理hashset是否有键。@Thomas。对不起,打字错误。删除它。你可以让它为你工作。如果你做一对一映射到键和值,那肯定是个坏主意。因为在集合中不能保证顺序。例如,如果你计划将苹果映射到1,香蕉映射到2,那么这个数据结构就行不通了。我说+1,但他为什么要使用另一个呢?他可以跳过
hashset
中的
equals
hashcode
hashcode
@user384706:OP要求一个可能的替代方案OK,但他可以扩展
hashset
想不出为什么它不会suffice@user384706:无需扩展
哈希集
。。。但是你为什么不发布一个答案来说明你的意思呢?好吧,我发布了一些东西。也许我没有正确地看到一些东西,这是一个有趣的选择!很难从OP的文本中判断,它是否会产生想要的结果,不过…我只是想知道是否有一些我没有看到的陷阱。如果你没有真正使用them@matt嗨,我现在把问题的措辞改了。解释得不太清楚。在任何时候我都不会更改键,我只会更新hashmap中该点所指向的值。
if(hashmap.containsKey(hashset))