java.util.Set.contains(Object o) 的奇怪行为

2024-01-16

The doc http://docs.oracle.com/javase/6/docs/api/java/util/Set.html#contains(java.lang.Object) about java.util.Set.contains(Object o) says:

当且仅当该集合包含元素 e 且满足以下条件时返回 true (o==null ? e==null : o.equals(e))。

也就是说,这是一个 POJO(如您所见,我覆盖了它equals方法):

public class MonthAndDay {

    private int month;
    private int day;

    public MonthAndDay(int month, int day) {
        this.month = month;
        this.day = day;
    }

    @Override
    public boolean equals(Object obj) {
        MonthAndDay monthAndDay = (MonthAndDay) obj;
        return monthAndDay.month == month && monthAndDay.day == day;
    }

}

那么请问为什么会打印以下代码false代替true?

Set<MonthAndDay> set = new HashSet<MonthAndDay>();
set.add(new MonthAndDay(5, 1));
System.out.println(set.contains(new MonthAndDay(5, 1)));
// prints false

解决方案是重写contains(Object o)方法,但原来的应该(几乎)完全相同,我错了吗?

Set<MonthAndDay> set = new HashSet<MonthAndDay>() {

    private static final long serialVersionUID = 1L;

    @Override
    public boolean contains(Object obj) {
        MonthAndDay monthAndDay = (MonthAndDay) obj;
        for (MonthAndDay mad : this) {
            if (mad.equals(monthAndDay)) {
                return true;
            }
        }
        return false;
    }

};
set.add(new MonthAndDay(5, 1));
System.out.println(set.contains(new MonthAndDay(5, 1)));
// prints true

当你覆盖equals(Object)你还需要覆盖hashcode().

具体来说,必须实施这些方法,以便如果a.equals(b) is true, then a.hashcode() == b.hashcode() is all true。如果不遵守这个不变量,那么HashMap, HashSet and Hashtable将无法正常工作。

技术细节如何hashcode() and equals(Object)应该表现在指定Object http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html API.


那么,如果你犯了这个错误,为什么基于哈希的数据结构会崩溃呢?基本上是因为哈希表的工作原理是使用哈希函数的值来缩小要与“候选”进行比较的值集的范围。如果候选对象的哈希码与表中某个对象的哈希码不同,则查找算法很可能不会与表中的对象进行比较……即使对象相等。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java.util.Set.contains(Object o) 的奇怪行为 的相关文章

随机推荐

  • Recyclerview - 顶部项目应与下一个项目重叠,依此类推

    我已经为这样的项目设置了负边距 public class ItemDecorator extends RecyclerView ItemDecoration private final int mSpace public ItemDecor
  • 如何为 WAI-ARIA 的加载动画添加标签?

    我正在努力解决网页上的一些可访问性问题 我有一个充当对话框的 div 并且在某个时刻显示一个包含加载动画和文本 工作 的 div 我不确定如何标记这两个项目 以便正确通知盲人用户有进度动画并且它正在工作 他应该等待 div style di
  • 斯坦福 CoreNLP 创建 edu.stanford.nlp.time.TimeExpressionExtractorImpl 时出错

    我正在尝试学习斯坦福 CoreNLP 库 我在发布的示例中使用 C https sergeytihon wordpress com 2013 10 26 stanford corenlp is available on nuget for
  • PHP 控制运算符 (@) 不起作用

    The 控制操作员 http php net manual en language operators errorcontrol php用于使所有警告 错误保持沉默 无论后果是什么 我想使用这个疯狂的工具 但我想我有一些奇怪的服务器配置 即
  • 如何在 Angular 2+ 的引导模式中创建谷歌自动完成?

    我正在使用角度谷歌地图 agm 我通过以下方式创建了谷歌自动完成功能 in html
  • 如何观察数据库的变化以更新LiveData

    我正在从以下位置迁移应用程序LoaderManager with Callbacks到一个实现使用ViewModel and LiveData 我想继续使用现有的SQLiteDatabase 主要实现工作正常 这Activity实例化Vie
  • Graphql,react-apollo如何在加载组件状态时传输变量以进行查询

    我有一个简单的反应组件 必须在用户询问时从服务器加载数据 问题是我不知道如何传输动态变量speakerUrl并在组件加载状态之前访问它 当然我可以从this props params 但是组件未加载 当我进行 graphql 查询时我无法访
  • 为什么嵌套订阅不好?

    我知道应该避免嵌套订阅并应该使用 rxjs 运算符 但是我发现的有关此问题的文章通常只是说嵌套订阅不好 而没有解释原因 除了说 可能会导致问题 我想知道是否有人可以帮忙解决这个问题 谢谢 很高兴您提出这个问题 因为这是一个常见问题 考虑类似
  • 将输入数据从 android 发送到 php

    这些代码在按下按钮后执行 我正在尝试将字符串数据发送到我的服务器中的 php 文件 但在我按下按钮后应用程序已停止 我可以知道这里有什么问题吗 非常感谢任何帮助 D HttpClient client new DefaultHttpClie
  • go-mysql:从 go 应用程序容器连接到 mysql 容器时不支持身份验证插件

    我正在将我的 linux docker 环境从我的 Mac 移植到我的笔记本电脑 我有 2 个 docker 镜像 一个是mysql latest数据库图像 另一个是go alpine应用程序服务器映像 在我的 Mac 上 我使用 bash
  • 使用 DateFormatter 将开始日期重置为 1970 年

    我有一个数据框 其中索引是每个月的第一个日期 size列是该月的频率 例如 Using index在数据帧上确认索引的类型是DatetimeIndex DatetimeIndex 2006 12 01 dtype datetime64 ns
  • Android Wear - 通知 - 图像跨度不起作用

    我在 Android 磨损通知中使用 ImageSpan 在通知中设置样式 但它不起作用 请告诉我如何在通知中使用 ImageSpan 的过程 如有帮助 我们将不胜感激 以下是我正在使用的示例代码 SpannableStringBuilde
  • 平方和递归[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我必须编写一个递归函数 sumSqu
  • 使用 Spring 控制器从 JavaScript 生成的表单提交列表 [重复]

    这个问题在这里已经有答案了 我正在使用 Spring Boot MVC 模式和 Thymeleaf 作为模板引擎构建一个应用程序 我有一个使用 JavaScript 生成列表的表单 以及一个带有 ModelAttribute期望将列表保存到
  • gcc 将所有警告视为错误,除了 X

    由于最好不提及的原因 我想将所有警告视为错误 除了一个警告 已弃用 我想将其视为警告 有没有比手动列出我想要视为错误的所有警告更方便的方法 你可以做 Werror Wno error deprecated
  • 使用管道从子进程进行 I/O 重定向 - winapi

    我正在使用一个提供 api 的应用程序 以便编写脚本更容易 基本上 当您编写有效的输入时 它会输出一个答案 我想使用该输出来发送更多输入 例如 Input
  • IF 语句中的多个 OR 或 AND 条件

    我对 IF 语句有一个基本疑问 假设我想将字符串 SUN 与字符数组 大小 3 匹配 if arr 0 S arr 1 U arr 2 N cout lt lt no else cout lt lt yes 是否在 If 语句中检查了所有条
  • FIndbug 未识别空指针异常

    我正在使用与 Eclipse 集成的 Findbugs 当我在项目上运行 findbugs 时 不会捕获以下代码以防止可能的空指针异常 在下面的代码片段中 对象测试很容易出现 findbugs 无法识别的空指针异常 Override pub
  • 如何隐藏php脚本的源代码? [复制]

    这个问题在这里已经有答案了 可能的重复 PHP 代码混淆器 https stackoverflow com questions 232736 code obfuscator for php 隐藏 PHP 源代码的最佳方法是什么 https
  • java.util.Set.contains(Object o) 的奇怪行为

    The doc http docs oracle com javase 6 docs api java util Set html contains java lang Object about java util Set contains