我可以将HashSet作为HashMap中的键吗?如果没有建议替代方案

stu*_*101 5 java hashmap set hashset

编辑:现在正确解释问题.

我有一个hashmap,我想存储一起看到的单词组(键)和它们在一起看到的行(值).这是我提出的结构:

HashMap<HashSet<String>, HashSet<Integer>> hm= ...
Run Code Online (Sandbox Code Playgroud)

输入:

  1. 芒果,香蕉,苹果

  2. 苹果,香蕉

  3. 桃子,海象

  4. 海象,桃子

当我逐行阅读时,我从行中的单词组合中创建新的临时键(尚未插入到hashmap中的哈希集).每个临时密钥是该行中单词的子集的哈希集.如果我的hashmap中已经存在临时密钥,我将检查它

if(hashmap.containsKey(hashset))
Run Code Online (Sandbox Code Playgroud)

我只是将新行添加到该键的相应值,如果没有,我在hashmap中创建一个新条目并处理它.

我决不改变现有的密钥.我只更新hasmmap中的相应值.

我的hashmap在读取文件的最后应该看起来像这样

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

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

...

问题是,

if(hashmap.containsKey(hashset))
Run Code Online (Sandbox Code Playgroud)

一段代码并不总是检测现有的密钥.为什么是这样?这种结构不允许吗?

谢谢

Mat*_*nry 7

这应该工作,但你需要注意键的可变性.如果您更改其中一个键的内容,其哈希码将会更改,并且您的地图将开始执行奇怪的操作.从javadoc Map:

注意:如果将可变对象用作映射键,则必须非常小心.如果在对象是地图中的键的情况下以影响等于比较的方式更改对象的值,则不指定映射的行为.这种禁令的一个特例是地图不允许将自己作为关键词包含在内.虽然允许映射将自身包含为值,但建议极其谨慎:equals和hashCode方法不再在这样的映射上很好地定义.

为避免这种情况,请Collections.unmodifiableSet()在创建时立即包装密钥,或者只使用ImmutableSetGuava.


Luk*_*der 4

可以,但是一旦您将 a 添加HashSet为 a 的键,HashMap您就不应该再次修改它,因为 aHashSet.hashCode()可能会发生变化,并且您将永远找不到您的了HashSet。换句话说,如果您正在做类似的事情,请确保您的密钥是不可变的HashSets(另请参阅Matt 的回答此处

另一种方法是使用MultiKeyMap来自公共集合MultiKey