【问题标题】:Compare two HashMaps keys for equality?比较两个 HashMaps 键是否相等?
【发布时间】:2013-08-05 19:05:44
【问题描述】:

我有两个HashMap<HashSet<String>, Long>,我想根据密钥进行比较。密钥是HashSet<String>,我可能需要更改为TreeSet<String>,但我认为没有必要。我将如何比较这些?

注意:地图仅用作单个 Set 的包装器。

for(HashMap<HashSet<String>, Long> entry : ListOfMaps) {
    if(entry.keySet().equals(entry2.keySet())) {
        // do something
    }
}

我想检查 Set1.equals(Set2)。

集合必须完全相同。由于每个HashMap&lt;Set&lt;String&gt;, Long&gt; 中只有一个Set&lt;String&gt;,所以我很紧张,因为我抓住了所有的钥匙,或者这样可以吗?

【问题讨论】:

  • 根据 javadoc docs.oracle.com/javase/6/docs/api/java/util/…,你所拥有的应该可以工作
  • 酷,只是确保因为我每个人只有一套。
  • 请注意,HashSets 没有排序,因此 .equals() 调用只是为了确保第一组中的所有字符串也出现在第二组中
  • 对。但它会检查每个 HashSet 中的所有字符串,以确保它们相等还是只是比较顺序。
  • Set[A, B, C] 会等于 Set[B, C, A] 对吧?

标签: java generics data-structures collections compareto


【解决方案1】:

Set 的 equals() 合约说:

如果给定对象也是一个集合,则返回 true,这两个集合具有相同的大小,并且给定集合的每个成员都包含在该集合中。这可确保 equals 方法在 Set 接口的不同实现中正常工作。

因此,只要 Set 实现遵循合同,您的代码就可以工作。

但是,这可能很危险,具体取决于您的代码对用作键的 Set 所做的操作。一旦对象被用作 Map 中的键,它就不应更改,因为这违反了 Map 的约定。

Map<Set<String>, T> map = HashMap<>();
Set<String> mySet = new HashSet<>();

mySet.add("first");
map.put(mySet, myValue);


Set<String> copyOfMySet = new HashSet<>(mySet);

//returns true
map.contains(copyOfMySet);

//modifying mySet
mySet.remove("first");

//this will now return false
map.contains(copyOfMySet);

【讨论】:

  • 我只是使用 Map 作为集合和时间戳的包装器。
  • 一般来说,我个人避免使用 Sets、Lists 等作为 map 的键,因为它很容易破坏......正如这篇评论的作者所指出的:)
  • 如果可能的话,最好使用简单变量,如整数、字符串等
  • 这里不使用 set 或任何集合的另一个原因可能是这种相等操作的复杂性。如果您使用任何字符串或 int 作为键,则比较两个哈希图将是 O(nm),其中 n 是键长度,m 是键数。现在如果你使用 hashset,那么它将是 O(nm*pq),其中 p 是 Set 的密钥长度,q 是密钥的数量。如果我在这里遗漏了什么,请告诉我您的意见。
猜你喜欢
  • 2013-08-18
  • 2021-09-14
  • 2023-03-11
  • 2010-12-05
  • 2016-03-06
  • 2014-09-20
  • 2013-06-27
  • 1970-01-01
相关资源
最近更新 更多