当前位置: 首页 > 知识库问答 >
问题:

在HashSet中插入对象的条件?

殳阳飙
2023-03-14

请耐心等待,因为我试图引入一个与许多活动线程直接矛盾的新概念。

在HashSet中插入对象的条件是什么?

查看源代码,它会关注:

if (e.hash == hash && ((k = e.key) == key || key.equals(k)))

完整代码位于:HashSet.java

所以,这取决于

  1. 哈希码
  2. 等于()
  3. == 即如果它们是相同的对象。

看看条件4。尽管equals()返回false,但对象会被添加到HashSet。在所有其他情况下,当且仅当equals()返回false时,对象才会被添加。因此,可以说(忽略条件4),一个对象是否会添加到HashSet的决定只是由equals()方法做出的。当被问及为什么我们使用hashCode()时,标准答案是它通过简单地比较整数来提高性能,因为短路运算符保存了equals()方法的执行。这个论点在许多线程中讨论过,比如如果我们无论如何都要检查等于,为什么我们要检查哈希?

然而,我发现这个论点是不正确的。如果equals()返回false,==返回true,哈希码实际上有一个决定。这是极不可能的,因为同一个对象通常会为equals()返回true,除非有人明确地(违反了equals)约定)重写equals方法,以便它为同一对象返回不同的值。尽管如此,这是一种可能性,java似乎正在为某些违约代码提供风险管理。你来吧!

共有3个答案

孙元明
2023-03-14
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))

e.hash == 出于效率原因,哈希在这种情况下存在,它是(在理智的情况下)执行的最快的测试,用于在第一个障碍时打折相等性。在程序处于有效状态的所有情况下(不违反 == .equals() .hashCode() 合约),它对 if 语句的最终结果没有逻辑影响。

由于破坏==. equals(). hashCode()契约而导致的条件不被考虑,因为这样的程序处于无效状态并且没有定义行为。违反契约下的效果可能会从实施变为实施,因此永远不应该依赖。

芮祺
2023-03-14

如果两个引用相等或相同(==),那么< code>equals()应该返回true。

如果equals()方法为两个对象返回true,那么hashCode()也需要为这两个对象返回相同的哈希值。

因此,让我们考虑8个场景的真值表,如下所示,只有4个有效场景。

| hashCode() | equals() |   ==   | add() |
| not-same   | false    | false  | true  |
| not-same   | false    | true   |   -   | - INVALID scenario (== vs equals)
| not-same   | true     | false  |   -   | - INVALID scenario (hash vs equals)
| not-same   | true     | true   |   -   | - INVALID scenario (hash vs equals)
| same       | false    | false  | true  |
| same       | false    | true   |   -   | - INVALID scenario (== vs equals)
| same       | true     | false  | false | 
| same       | true     | true   | false |

在问题表中;S. No 4

闽朝
2023-03-14

HashSet 要求传递给它的对象遵守 hashCode 的约定并等于 — 如果它们不这样做,那么垃圾输入垃圾。等于的协定规定,如果两个引用是 ==,则它们必须相等。因此,上面的条件 4 违反了相等契约,因此违反了 HashSet 的契约,因此 HashSet 在提出这样一组条件时没有义务采取有意义的行动。

条件5也会破坏合同。

 类似资料:
  • 问题内容: 伙计们,我只是花了很多时间来尝试查找-我应该缺少一些基本知识。 我有一个python对象,我要做的就是将此对象插入mondodb中。 这就是我所拥有的: 抛出此错误: 好像是因为json.dumps()返回一个字符串。 现在,如果我在插入之前对值进行加载,则效果很好: 最直接的方法是什么? 谢谢! 问题答案: 是什么在你最初的代码? 它不应该是类实例 这应该工作:

  • 问题内容: 在Java API中,HashSet的实现使用Object作为 内部HashMap 的值, 但是HashMap允许其值为null。我认为并不需要填写该值,那么为什么要这样做呢? 问题答案: 因为HashSet合同指定了返回值(true如果指定的对象存在并被删除)。为此,它使用包装的 方法返回已删除的值。 如果要存储而不是存储对象,则对 的调用将返,这与尝试删除不存在的对象的结果没有区别

  • 我在Laravel5.3中遇到了一个问题,我查看了文档,也搜索了web,但没有找到任何内容。 我使用Laravel关系连接两个表。现在,我希望在用户提交表单后,同时在两个表上插入数据。这里的问题是第一个表是主要的一个说“用户”,第二个说“xyz”属于第一个表。表"xyz"包含连接两个表的"users_id"列。而显然“users_id”是“用户”表的“id”列。 现在问题来了,我想插入数据在用户表

  • 问题内容: 我只想将对象推入mongodb中的对象数组 并将对象推入需要执行的上述文档中 那么我如何使用 mgo驱动程序* 实现相同的功能 * 问题答案: 请尝试以下操作:

  • 我正在使用Envers来审核表,但它正在为未知/不存在的表创建一些审核表。它看起来像多对一关系的多对多关系审计表。 这是对的吗?如果是,为什么? 但当我尝试删除和HorarioFixo时,我遇到了一个错误。 我收到的错误: 这是SQL重复: 所有这些都是代码的一部分。如果你需要更多,请留下评论。 我的班级: 我的映射: 新罕布什尔州和恩维尔斯配置:

  • 问题内容: 比方说,我有一个名为接口,以及三种实现- ,和。 现在,我希望每当我的托管bean(或任何Web组件)收到一条消息时,便在所有社交网络中共享它。我试过了: 但这没有用(部署错误)。(也尝试了预选赛-同样的结果) 那么,有没有办法注入接口的所有(或某些)实现的列表? 我知道给定注入点不应包含多个可能的bean的规则。我想我可以通过创建一个产生列表的生产者并使用来实现这一点,但这对于这项任