"=="与"equals"方法
"=="的含义
- 基本数据类型:byte,short,int,long,float,double,char,boolean。通过"=="比较的是它们的值
- 引用数据类型:类,接口,数组。通过"=="比较的是他们的(堆)内存地址
“equals()方法”
Object.hashCode()方法
/**
* 返回对象的哈希代码值。支持此方法是为了获得哈希表的好处,例如 {@link java.util.HashMap} 提供的哈希表。
* {@code hashCode} 的总合同是:
* 每当在 Java 应用程序执行期间在同一对象上多次调用它时,{@code hashCode} 方法必须始终返回相同的整数,前提是没有修改对象上的 {@code equals} 比较中使用的信息。此整数不必从一次应用程序执行到同一应用程序的另一次执行保持一致。
* 如果根据 {@code equals(Object)} 方法将两个对象相等,则在两个对象中的每一个上调用 {@code hashCode} 方法必须产生相同的整数结果。
* 如果根据 {@link java.lang.Object#equals(java.lang.Object)} 方法,两个对象不相等,则在两个对象中的每一个上调用 {@code hashCode} 方法必须产生不同的整数结果。但是,程序员应该知道,为不相等对象生成不同的整数结果可能会提高哈希表的性能。
* 尽管合理实用,但由类 {@code Object} 定义的哈希Code 方法确实为不同的对象返回不同的整数。(这通常是通过将对象的内部地址转换为整数来实现的,但 Java™ 编程语言不需要这种实现技术。
*/
public native int hashCode();
Object.equals()方法
/** 指示某个其他对象是否"等于"此对象。
* {@code等于} 方法在非空对象引用上实现等价关系:
* 它是自反的:对于任何非空引用值 {@code x},{@code x.equals(x)} 应返回 {@code true}。
* 它是对称的:对于任何非空引用值 {@code x} 和 {@code y},{@code x.equals(y)} 应返回 {@code true},当且仅当 {@code y.equals(x)} 返回 {@code true}。
* 它是可传递的:对于任何非空引用值 {@code x}、{@code y} 和 {@code z},如果 {@code x.equals(y)} 返回 {@code true} 并且 {@code y.equals(z)} 返回 {@code true},则 {@code x.equals(z)} 应返回 {@code true}。
* 它是一致的:对于任何非空引用值 {@code x} 和 {@code y},多次调用 {@code x.equals(y)} 一致地返回 {@code true} 或一致地返回 {@code false},前提是没有修改对象上的 {@code equals} 比较中使用的信息。
* 对于任何非空引用值 {@code x},{@code x.equals(null)} 应返回 {@code false}。
* 类 {@code Object} 的 {@code equals} 方法在对象上实现了最具辨别力的可能等价关系;也就是说,对于任何非空引用值 {@code x} 和 {@code y},当且仅当 {@code x} 和 {@code y} 引用同一对象({@code x == y} 具有值 {@code true}),此方法返回 {@code true}。
* 请注意,每当覆盖此方法时,通常都需要重写 {@code hashCode} 方法,以便维护 {@code hashCode} 方法的一般合约,该方法规定相等对象必须具有相等的哈希代码。 * * * @param obj 作为要比较的引用对象。
* @return {@code true},如果此对象与 obj 参数相同;{@code false} 否则。
* @see #hashCode()
* @see java.util.HashMap
*/
public boolean equals(Object obj) {
return (this == obj);
}
- Object是所有类的基类,Object的equals()方法直接比较this与obj的(堆)内存地址,判断this与obj是否为同一对象。
- 若使用equals()方法判断对象的属性值是否一致 ,需重写该对象类的equals()与hashCode()方法,且保证相同属性对象hashCode()方法返回值相同,不同属性对象的返回值不同。
- 《Head First Java》
当你把对象加入 HashSet 时,HashSet 会先计算对象的 hashCode 值来判断对象加入的位置,同时也会与其他已经加入的对象的 hashCode 值作比较,如果没有相符的 hashCode,HashSet 会假设对象没有重复出现。但是如果发现有相同 hashCode 值的对象,这时会调用 equals() 方法来检查 hashCode 相等的对象是否真的相同。如果两者相同,HashSet 就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。这样我们就大大减少了 equals 的次数,相应就大大提高了执行速度。
-
重写equals()方法时必须重写hashCode()方法,为什么不只提供equals()方法:
- equals()与hashCode()方法都是用来比较对象的,但在一些容器(hashSet和hashMap)中,通过hashCode()方法判断元素是否存在容器中更高效。如果只重写equals()不重写hashCode(),会导致相等的对象hashCode却不相等,在使用上述的容器时,会发生问题。
-
为什么不只提供hashCode()方法
- hashCode()方法的返回值相等,对象不一定相等(hash冲突)
- hashCode()返回值相等且equals()方法返回true,则认为对象相等
- hashCode()返回值不向等,则认为对象不相等