转自:http://www.sunxin.org/forum/thread/19720.html
先谈equals。
equals是Object类提供的方法之一,众所周知,每一个java类都继承自Object类,
所以说每一个对象都有equals这个方法。而我们在用这个方法时却一般都重写这个方法,why?
Ok,先看一个Object类中equals()方法的源代码:
- public boolean equals(Object obj) {
- return (this == obj);
- }
从这个方法中可以看出,只有当一个实例等于它本身的时候,equals()才会返回true值。通俗地说,此时比较的是两个引用是否指向内存中的同一个对象,也可以称做是否实例相等。而我们在使用equals()来比较两个指向值对象的引用的时候,往往希望知道它们逻辑上是否相等,而不是它们是否指向同一个对象——这就是我们通常重写这个方法的原因。
在程序员之家论坛中有这样一篇文章《全面理解Java中的String数据类型》(链接http://www.phome.asia/forum/thread/19667.html) ,在这篇文章中,String s1 = new String(“kvill”),String s2 = new String(“kvill”); s1.equals(s2)为ture,说明String类中已经重写了equals()方法,如果不重写equals()方法,那么s1.equals(s2)默认比较两个对象所指向的内存地址是否相同,返回值必然为false。
重写equals()方法看起来非常简单,但是有许多改写的方式会导致错误,并且后果非常严重。要想正确改写equals()方法,你必须要遵守它的通用约定。下面是约定的内容,来自java.lang.Object的规范,equals方法实现了等价关系,以下是要求遵循的5点,这5点都是当年数学的概念啊……,呵呵,且看:
1. 自反性:对于任意的引用值x,x.equals(x)一定为true。
2. 对称性:对于任意的引用值x 和 y,当x.equals(y)返回true时,y.equals(x)也一定返回true。
3. 传递性:对于任意的引用值x、y和z,如果x.equals(y)返回true,并且y.equals(z)也返回true,那么x.equals(z)也一定返回true。
4. 一致性:对于任意的引用值x 和 y,如果用于equals比较的对象信息没有被修改,多次调用x.equals(y)要么一致地返回true,要么一致地返回false。
5. 非空性:对于任意的非空引用值x,x.equals(null)一定返回false。
了解了equals重写,我们再看hashCode()这个方法,hashcode()这个方法也是从object类中继承过来的,在object类中定义如下:
public native int hashCode();
说明是一个本地方法,它的实现是根据本地机器相关的。再看它比较“官方”的详细说明:hashCode()返回该对象的哈希码值,该值通常是一个由该对象的内部地址转换而来的整数,它的实现主要是为了提高哈希表(例如java.util.Hashtable提供的哈希表)的性能。
你可以对它的这样“官方式”的定义漠视,但以下这一点你必须铭记:在每个重写了equals方法的类中,你必须也要重写hashCode方法。如果不这样做的话,就会违反Object.hashCode的通用约定,从而导致该类无法与所有基于散列值(hash)的集合类结合在一起正常运行。
hashCode()的返回值和equals()的关系如下:
如果x.equals(y)返回“true”,那么x和y的hashCode()必须相等。
如果x.equals(y)返回“false”,那么x和y的hashCode()有可能相等,也有可能不等。
说了这么多,他们之间的具体关系还是看个例子好,以下是51px中吴老师的一个例子。
- public class TestEquals {
- public static void main(String args[]) {
- Student s1 = new Student("张一", 6);
- Student s2 = new Student("张一", 6);
-
- if (s1.equals(s2)) {
- System.out.println("相同 s1的代码:" + s1.hashCode() + " s2的代码:"
- + s2.hashCode());
- } else {
- System.out.println("不相同");
- }
- }
- }
-
- class Student {
- private int age;
- private String name;
-
- public Student() {
- }
-
- public Student(String name, int age) {
- this.age = age;
- this.name = name;
- }
-
- public int getAge() {
- return age;
- }
-
- public void setAge(int age) {
- this.age = age;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public int hashCode() {
- return (this.name.hashCode() + this.age) * 31;
- }
-
- public boolean equals(Object obj) {
- boolean result = false;
- if (obj == null) {
- result = false;
- }
- if (this == obj) {
- result = true;
- }
-
- if (obj instanceof Student) {
- Student stu = (Student) obj;
- if (stu.getName().equals(this.name) && stu.getAge() == (this.age)) {
- result = true;
- }
-
- } else {
- result = false;
- }
- return result;
- }
- }
相关推荐
浅谈Java中hashCode的正确求值方法 hashCode是一种常用的散列函数,在Java中它是一个对象的整数表示,用于标识对象的唯一性。在Java中,每个对象都有一个hashCode,这个hashCode可以通过hashCode()方法来获取。...
同时,需要注意的是,如果自定义了类并且想要比较对象内容,记得要同时重写`equals()`和`hashCode()`方法,以保持两者的一致性,这在使用HashMap、HashSet等容器时尤为重要。 此外,当我们涉及到数组或者集合时,`...
这些集合依赖于`hashCode()`和`equals()`方法来快速定位和区分不同的对象。 `hashCode()`方法的主要作用在于提高查找效率。当向哈希集合中添加对象时,首先会调用对象的`hashCode()`方法来计算哈希码。如果哈希码在...
3. **字符串比较**:介绍equals()、compareTo()和hashCode()等方法的使用,以及字符串的相等性和排序规则。 4. **字符串与字符数组**:阐述字符串与char数组之间的转换,以及它们在内存中的表示。 5. **字符串常量池...
### 浅谈Java集合框架 Java集合框架是一个用于存储、操作和检索一组对象的强大工具集。集合框架的设计目的是为了提供一套高效且灵活的数据结构来满足不同的应用需求。本篇文章将详细探讨Java集合框架中的一些核心...
在使用Java集合框架时,重写hashCode()和equals()方法是非常重要的,尤其是在使用Set集合时。这两个方法决定了集合如何识别元素的唯一性。如果使用不当,可能会导致相同元素无法被正确识别,从而影响集合的操作结果...
- Equals()和HashCode()的作用:理解equals方法和hashCode方法在Java中的重要性,以及它们如何影响对象比较和集合操作。 - Sleep()和Wait()的区别:清楚这两个方法在多线程环境下的使用及其背后的原理。 - IO与NIO的...
需要注意的是,如果两个对象相等(根据`equals()`方法),它们的`hashCode()`值必须相同,以符合`equals()`和`hashCode()`的一致性原则。 `getClass()`方法用于获取对象所属的运行时类。它返回一个`Class`对象,该...
- **4.5 equals()和hashCode()的作用**:详细说明`equals()`方法与`hashCode()`方法的重要性及其正确实现方式。 - **4.6 sleep()和wait()的区别**:对比`Thread.sleep()`与`Object.wait()`两种线程等待机制的不同...
- **equals()和hashCode()作用**:`equals()`用于比较两个对象是否相等,而`hashCode()`返回对象的哈希码值,常用于散列表(如`HashMap`)中确定对象存储位置。两者通常需要配合使用,以确保对象在散列表中的一致性...
- **4.5 equals()和hashCode()作用:** - `equals()`用于比较两个对象是否相等。 - `hashCode()`返回对象的哈希码值,用于散列数据结构如哈希表。 - 如果两个对象相等(`equals()`返回true),则它们必须具有相同...
Object 类的通用方法,如 equals()、hashCode() 和 toString(),是理解和重写这些方法的基础。继承是面向对象编程的核心概念,讨论了单继承和多层继承的特点。反射机制允许程序在运行时检查类的信息并动态调用方法,...