【问题标题】:HashSet<String> .contains()HashSet<String> .contains()
【发布时间】:2012-02-23 04:23:40
【问题描述】:

我在使用 .contains 检查字符串是否存储在 HashSet 中时遇到问题。

import java.util.HashSet;

public class Controller
{
    private Queue<String> queue;
    private HashSet<String> blocked;

    public Controller()
    {
        queue = new Queue<String>();
        blocked = new HashSet<String>();
    }

    public void add(String item)
    {        
        if (!(blocked.contains(item))) queue.add(item);
    }
}

我环顾四周,明白我需要重写 .equals 方法。这是否意味着我必须创建一个扩展 HashSet 的新类,然后声明该新类的一个实例来代替“HashSet blocked;”?

我知道简单地使用 == 来比较两个字符串不起作用的原因,但我很困惑,因为下面的代码在某些情况下似乎确实有效,但并非全部。

任何建议将不胜感激!

问候

【问题讨论】:

  • 该代码应该可以工作; String 会覆盖 equals()hashCode()
  • 什么情况下不起作用?记住区分大小写。
  • 我怕你误会了。如果您在 HashSet 中使用对象,则该对象应该具有良好的 hashCodeequals 方法,而不是 HashSet 本身。由于String 带有它自己的equalshashCode 方法,因此您不需要做额外的工作。您希望该代码做什么以及为什么“它不起作用”?
  • 感谢您的快速回复。我说它不起作用,因为“块”HashSet 中的字符串仍被添加到队列中。我已经尝试打印到控制台进行检查,并且肯定会发生。这当然与案件无关。会不会是字符串中包含了打印到控制台时看不到的字符?

标签: java collections hashset


【解决方案1】:

您不需要重写 equals 方法 - String 已经有一对非常好的hashCode/equals,它们在 CPU 周期和将不同的字符串分配到不同的哈希桶方面非常有效。

放置在散列集中的项目需要一对hashCode/equals 方法,以启用容器的正确工作:hashCode 决定放置对象的散列“桶”,@987654327 @ 解决具有相同哈希码的不相等对象之间的冲突。

维基百科在哈希表上有一个图解article。通读它以提高您对 hashCode/equals 概念的理解,它们是在包括 Java 在内的任何语言中使用未排序关联容器的基础。

【讨论】:

  • 感谢您的快速回复。我说它不起作用,因为“块”HashSet 中的字符串仍被添加到队列中。我已经尝试打印到控制台进行检查,并且肯定会发生。这当然与案件无关。会不会是字符串中包含了打印到控制台时看不到的字符?
  • @stasis 打印到控制台时,请考虑在您的单词周围添加“保护字符”——例如,单引号或方括号。这样您就可以判断一个单词是否有尾随空格,而另一个单词没有。我假设你的代码不是多线程的,对吧?
  • 感谢您的链接。我得出的结论是,我需要通过浏览来覆盖 equals 方法,并认为这将是一个类似的问题。继续我不应该重写 .equals 以使 .contains 工作的事实,你为什么认为 .contains 在这种情况下对我不起作用?再次感谢您的帮助
  • 是的,我周围有容器要检查,没有空白字符。目前它不是多线程的,但我确实计划这样做
  • @stasis 任何在你的代码中不起作用的东西都会因为与 String 的 hashCode/equals 无关的原因而被破坏。例如,一个项目可以添加到blocked之后它已添加到queue
猜你喜欢
  • 1970-01-01
  • 2015-10-06
  • 2011-12-13
  • 1970-01-01
  • 1970-01-01
  • 2018-05-07
  • 2018-08-27
  • 2012-03-16
  • 1970-01-01
相关资源
最近更新 更多