【问题标题】:Java HashSet<String> collision of objectJava HashSet<String> 对象的冲突
【发布时间】:2017-10-29 13:29:22
【问题描述】:

我使用HashSet&lt;String&gt; 来存储值,但某些字符串具有相同的哈希码。 HashSet 如何处理冲突。

List<ClassA> getValuesFromA(){

}

List<ClassA> getValuesFromB(){

}

Set <String> a = new HashSet<String>(getValuesFromA()); // data overwritten due to hash code collision

Set <String> b = new HashSet<String>(getValuesFromB()); // data overwritten due to hash code collision

a.removeAll(b);
a.stream().forEach(t -> t.setSomeValue(X));
b.addAll(a);

我正在使用 HashSet 为每个元素在 O(1) 中找到负 b,然后找到 b + (a - b)。但是在 HashSet 中存储数据时,一些数据会被覆盖。有没有人知道在不更改哈希方法或数据结构的情况下执行此操作?

【问题讨论】:

  • "但是在 HashSet 中存储数据时,我丢失了一些数据。"请清楚得多。请注意,哈希码冲突不会丢失数据 - 它们只会稍微降低查找值的效率。请提供minimal reproducible example,因为您的问题目前尚不清楚。
  • (你可能只想使用retainAll,顺便说一句。)

标签: java collections hashset


【解决方案1】:

但是在 HashSet 中存储数据时,我丢失了一些数据。如何 处理这个?

hashCode() 结果中的冲突不会丢失或覆盖 HashSet 中具有相同哈希码的对象。
具有相同哈希码的两个对象可以存储在同一个 HashSet 中。

在您的示例代码中,您可以这样做:

Set <String> a = new HashSet<String>(getValuesFromA());

Set <String> b = new HashSet<String>(getValuesFromB());

a.removeAll(b);

a 中删除b 中包含的所有值。
所以a 将包含a 减去b values
你做了一个排除。

然后你做:

b.addAll(a);

它不是一个交集,因为您添加到b 的只是a包含在b 中。

您应该使用 Jon Skeet 建议的 retainAll() 方法,这似乎符合您的要求:

仅保留该集合中包含在 指定集合

Set<String> intersectionSet = new HashSet<>(getValuesFromA());    

intersectionSet.retainAll(getValuesFromB());

【讨论】:

    猜你喜欢
    • 2012-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-30
    • 1970-01-01
    • 2015-02-10
    • 1970-01-01
    • 2019-04-20
    相关资源
    最近更新 更多