为什么Java使用’equals’代替’==’来检查对象在Map中的存在?

假设我想将一个键及其值放在Map中。

我相信这是Java的作用:

  1. 获取密钥的Hashcode并检查映射中是否存在具有相同哈希码的密钥。

  2. 如果没有具有相同Hashcode的密钥,则可以将密钥放入Map中。

  3. 如果存在具有相同Hashcode的密钥,则使用equals来确定密钥是否可以放入Map中。

我的问题是为什么在这个过程中不使用==而不是equals

做你的建议将打破equals / hashCode串联的整个概念。 equalshashCode都将变得无用,甚至不应该存在。

Java允许程序员为他的类定义相等集; 如果他不想这样做,他可以简单地选择不使用覆盖的equalshashCode – 并最终确定你提出的语义。

举一个具体的例子,根据你的提议,这将在地图中创建两个单独的条目:

 Map map = new HashMap<>(); map.put(10_000, "a"); map.put(10_000, "a"); 

这是因为文字10_000每次都会被自动装入一个新的Integer实例,在你的语义下,它是两个独立的键。 然后,声明

 System.out.println(map.get(10_000)); 

会打印null ,因为你当然使用第三个键来获取。 事实上,不可能通过密钥检索任何地图值。

==从面向对象的意义上来说并没有多大意义。

new Integer(3)new Integer(3)以及new Integer(2+1)都应该被认为是相等的。 其他一切都让人感到困惑,这就是equals描述的内容。 如果没有这个,当你不再引用原始密钥时,就不可能从HashMap()中提取任何东西。 当根据数据库中的数据将内容放入HashMap时,使用来自用户的输入在HashMap中查找内容也是不可能的。

如果您正在寻找==equalshashCode周围的问题,那么==应该真正意味着“等于”,并且参照完整性应该有一些模糊的句柄,没有人真正知道,因为你总是从不使用它。 顺便说一句,这正是Scala所做的其他语言。

在java中,==用于检查引用相等性,而equals()和hashCode()一起作为对象相等的“单一概念” 。
如果您需要使用==使用IdentityHashMap的Map。

键是对象类型,所有类都是从Object类中派生出来的。 如果您正在使用由您编写的类的键,并且您没有在类中重写equals方法,那么会发生什么? 这是答案:

无论您的类中的两个对象是否具有完全相同的属性值,但仍然是equals的结果将为false。 仅仅因为默认等于impelemtations将检查两个对象是否指向相同的内存位置。 这正是==比较所做的。

现在来到hashals使用equals而不是==。 这是因为当您尝试将键放入映射时,JVM会尝试检查两个对象是否相等。 JVM检查此相等性的唯一智能是使用equals方法。 并且通过其默认实现,它将执行== comparision将执行的操作。 但正如我上面提到的,如果两个对象具有相同的属性,它们实际上是相等的。 但遗憾的是==比较不能进行属性比较并提出真正的价值。 因此,重写equals方法或使用equals方法在逻辑上非常重要,同时将值存储在Map中。

因为“==”用于比较2个对象的引用和.equals()的内容。使用Java Collection JFrame时的一个重要规则是覆盖equals方法,还有.hashCode()这样如果你有2个对象具有相同的内容以映射在相同的密钥(哈希码)。 如果不覆盖.enquals,则调用的方法将来自Object类,该类将引用与“==”进行比较。覆盖.hashCode()时的一个重要细节是使用final字段。