如果我将覆盖hashCode()
方法,则会降低应用程序的性能。我在我的应用程序的许多地方都重写了这个方法。
答案 0 :(得分:6)
是的,如果hashCode方法以错误的方式实现,则会降低散列集合的性能。 hashCode方法的最佳实现应该为唯一对象生成唯一的hashCode。唯一的hashCode将避免冲突,并且可以以O(1)
复杂度存储和检索元素。但是只有hashCode方法无法做到,你需要覆盖equals方法来帮助JVM。
如果hashCode方法无法为唯一对象生成唯一哈希,那么您有可能在桶中持有多个对象。当您有两个具有相同散列的元素但equals方法为它们返回false时,会发生这种情况。所以每次发生这种情况时,元素都会被添加到哈希桶的列表中。这将减慢元素的插入和后退。这将导致get方法的O(n)
复杂性,其中n是存储桶中列表的大小。
注意:当您尝试为hashCode实现中的唯一对象生成唯一哈希时,请确保编写简单的算法来执行此操作。如果用于生成哈希的算法太重,那么您肯定会看到哈希集合上的操作性能很差。因为哈希集合上的大多数操作都会调用hashCode方法。
答案 1 :(得分:3)
如果在正确的位置使用正确的数据结构,
会提高性能例如:Object中正确的哈希码实现几乎可以将O(N)转换为O(1)以进行HashMap
查找
除非你在hashCode()
方法
每次必须使用对象处理哈希数据结构时,如果你有大量的hashCode()
方法(不应该这样),它会调用hashCode()
方法
答案 2 :(得分:3)
这完全取决于您如何实施hashCode
。如果您正在进行大量昂贵的深度操作,那么可能也是如此,在这种情况下,您应该考虑缓存hashCode
的副本(如String
那样)。但是一个体面的实现,例如HashCodeBuilder
,将不会是一个大问题。拥有良好的hashCode
值可以使HashMap
和HashSet
等数据结构中的查找速度更快,如果覆盖equals
,则需要覆盖{{} 1}}。
答案 3 :(得分:3)
Java hashCode()
无论如何都是一个虚函数,因此它被覆盖并使用重写方法这一事实并没有造成性能损失。
真正的区别可能是该方法的实施。默认情况下,hashCode()
的工作方式如下(source):
尽可能合理实用,由hashCode方法定义 class Object确实为不同的对象返回不同的整数。 (这个 通常通过转换内部地址来实现 将对象转换为整数,但这种实现技术不是 JavaTM编程语言所要求的。)
因此,只要您的实现如此简单,就不会有性能损失。但是,如果您基于许多字段执行复杂的计算操作,调用许多其他函数 - 您会注意到性能损失,但仅仅因为您的hashCode()
执行了更多操作。
还存在低效hashCode()
实施的问题。例如,如果您的hashCode()
只返回值1
,那么使用HashMap
或HashSet
的速度将明显慢于正确实施。有一个很好的问题涉及在SO上实施hashCode()
和equals()
的主题:What issues should be considered when overriding equals and hashCode in Java?
还有一点需要注意:请记住,无论何时实施hashCode()
,您都应该实施equals()
。此外,您应该小心谨慎,因为如果您编写无效的hashCode()
,您可能会破坏各种集合的等式检查。
答案 4 :(得分:2)
在类中重写hashCode()本身不会导致任何性能问题。但是,当将此类的实例插入HashMap HashSet或等效数据结构时,hashCode()&可选地,调用equals()方法来识别将该元素放入的右桶。同样适用于Retrival Search&删除。
由其他人发布的表现完全取决于hashCode()的实现方式。 但是,如果根本不使用特定类的equals方法,则不必重写equals()和hashCode(),但如果重写equals(),则必须重写hashcode()
答案 5 :(得分:1)
正如前面提到的所有评论一样,哈希码用于集合中的散列,或者它可以用作equals中的负面条件。所以,是的,你可以减慢你的应用程序。显然有更多的用例。
首先,我会说这种方法(是否重写它)取决于你所谈论的对象的类型。
“相同”可以表示“相同实例”。当您的对象为entity或“相同”可以表示具有所有相同属性的对象时,“相同”可以表示具有相同(数据库)标识符的对象。到目前为止它似乎会影响性能。
但是其中一个属性可以是一个可以根据需要评估hashCode()的对象,现在,当您在根对象上调用hash-code方法时,您总能得到对象树的哈希码的评估。
那么,我会推荐什么?您需要定义并阐明您想要做的事情。你真的需要区分不同的对象实例,或者标识符是至关重要的,还是它是值对象?
它还取决于不变性。当使用所有构造函数属性(只有get)构造对象时,可以计算一次hashcode值,并在调用hashcode()时始终使用它。或者另一种选择是在任何属性发生变化时始终计算哈希码。您需要确定大多数情况是读取值还是写入它。
我要说的最后一件事是,只有当你知道自己需要它并且知道自己在做什么时才覆盖hashCode()方法。
答案 6 :(得分:1)
hashCode方法的主要目的是允许对象成为哈希图中的键或哈希集的成员。在这种情况下,对象还应该实现equals(Object)方法,该方法与hashCode实现一致:
If a.equals(b) then a.hashCode() == b.hashCode()
如果在同一对象上两次调用hashCode(),则只要不更改对象,它应该返回相同的结果
从性能的角度来看hashCode
下一个目标是检查仍有多少具有唯一性的标识符具有代码。如果您有太多非唯一的哈希码,请改进您的hashCode方法或增加允许的哈希码值范围。在理想情况下,所有标识符都将具有唯一的哈希码。
答案 7 :(得分:0)
如果你将覆盖hashCode()方法,它会降低application的性能。如果在正确的地方使用了正确的数据结构,它会提高性能,
例如:Object中的正确hashcode()实现几乎可以将O(N)转换为O(1)以进行HashMap查找。无论你在hashCode()方法中做了太多复杂的操作