hashcode()/equals()/==
==
当 == 左右两边是基本类型的时候,比较的是数值是否相等;
当 == 左右两边是对象(引用)类型的时候,比较的是p和p2这两个对象所指向的堆中的对象地址
对于 == 来说,不管是比较基本数据类型,还是引用数据类型的变量,其本质比较的都是值,只是引用类型变量存的值是对象的地址。
equals()
equals()方法存在于Object类中,所以所有类都具有equals()方法,但是基本数据类型就没有这个方法了。
当没有重写equals()方法时候,通过equals()方法进行比较的时候,其实就等价于通过==
比较两个对象。因为在没有重新equals方法的情况下默认都使用的是Object类的equals()方法;
重写了equals()方法的时候,根据重写的逻辑返回true或false
hashcode()
这个函数是用来把对象放进hashtable的,当我们想把一个对象放进hashtable的时候,我们必须要知道这个对象应该放在哈希表的哪个槽位上,hashcode()就是用来计算这个槽位的。
提出一个问题,如果equals的两个对象,我们要把他们都放进hashtable吗,我们希望他们冲突吗,答案是肯定的,我们希望只有一个对象进去,那么如果我们改写了equals,以对象的属性判定对象是不是相等,那就必须要重写hashcode,以对象的属性生成对象的槽位。如果只重写equals但不重写hashcode那么就会出现,我们认为相同的两个对象但是他们的hashcode不一样,那这两个对象根本不会发生冲突,他们都可以进入hashtable,这不是我们想要看到的。所以,
重写了equals就必须重写hashcode
我们希望散列表满足一个原则,如果两个对象equals,那么他们应该映射在同一个槽位上,进而通过equals函数发生冲突,只保留一个对象进入hashtable
如果只重写equals,两个对象的虽然确实不是同一个对象,但是因为里面的属性一样,所以重写过的equals把他们看成同一个对象,但是hashcode仍然按照地址计算,发现他们不一样,就会把他们安排到不同的槽位上,这样两个对象就不发生冲突而同时进入了hashtable,这不是我们想要看到的。
equals的两个对象必须具有相同的hashcode
下面看看JAVA官方文档怎么说
hashcode
hashCode
public int hashCode()
Returns a hash code value for the object. This method is supported for the benefit of hash tables such as those provided by HashMap.
The general contract of hashCode is:
Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.
As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the Java™ programming language.)
Returns:
a hash code value for this object.
See Also:
equals(java.lang.Object), System.identityHashCode(java.lang.Object)
翻译一下
hashCode
public int hashCode()
返回对象的散列码值。支持此方法是为了使用哈希表(如HashMap提供的哈希表)。
hashCode的总契约是:
在Java应用程序的执行过程中,只要在同一对象上多次调用hashCode方法,hashCode方法必须始终返回相同的整数,前提是对象上用于相等比较的信息没有被修改(执行过程中必须始终保持一致,但是如果我们把程序关了再次执行,第二次程序执行过程中的hascode值不必与第一次程序执行过程中的hascode一致,只要单次执行过程内部保持一致即可)。该整数不必在应用程序的一次执行与另一次执行之间保持一致。
如果根据equals(Object)方法两个对象相等,那么对这两个对象中的每一个调用hashCode方法必须产生相同的整数结果。
根据equals(java.lang.Object)方法,如果两个对象不相等,则不要求对这两个对象中的每一个调用hashCode方法必须产生不同的整数结果。然而,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。
在合理可行的情况下,由Object类定义的hashCode方法确实为不同的对象返回不同的整数。(这通常通过将对象的内部地址转换为整数来实现,但是Java编程语言不需要这种实现技术。)
返回:
该对象的哈希码值。
参见:
= (java . lang . object), System.identityHashCode (java . lang . object)
equals
equals
public boolean equals(Object obj)
Indicates whether some other object is "equal to" this one.
The equals method implements an equivalence relation on non-null object references:
It is reflexive: for any non-null reference value x, x.equals(x) should return true.
It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
For any non-null reference value x, x.equals(null) should return false.
The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true).
Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.
Parameters:
obj - the reference object with which to compare.
Returns:
true if this object is the same as the obj argument; false otherwise.
See Also:
hashCode(), HashMap
翻译一下
equals
public boolean = (Object Object)
指示其他对象是否“等于”此对象。
equals方法在非空对象引用上实现等价关系:
- 它是自反的:对于任何非空的引用值x, x.x equals(x)应该返回true。
- 它是对称的:对于任何非空引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)应该返回true。
- 它是可传递的:对于任何非空引用值x, y和z,如果x.equals(y)返回true并且y.equals(z)返回true,则x.equals(z)应该返回true。
- 它是一致的:对于任何非空引用值x和y,如果不修改对象上的相等比较中使用的信息,则多次调用x.equals(y)一致地返回true或一致地返回false。
对于任何非空的引用值x, x.equals(null)应该返回false。
Object类的equals方法在对象上实现了最具区别性的可能的等价关系;也就是说,对于任何非空引用值x和y,当且仅当x和y引用同一对象(x == y的值为true)时,此方法返回true。
请注意,每当覆盖hashCode方法时,通常都需要覆盖该方法,以便维护hashCode方法的一般契约,该契约规定相等的对象必须具有相等的哈希码。
参数:
Obj -要与之比较的引用对象。
返回:
如果此对象与obj参数相同,则为True;否则错误。
参见:
hashCode (), HashMap