以前一直只听某些所谓的高人经常说什么“那就重写equals方法嘛”或者“XXX 条件下,要重写equals方法”啊什么的论语。但自己从来没有看见过,理解过其中的究竟。也从来没有写过。更不知道在什么时候可以用,以及怎么用。原来发现人参泡在“自己不知道自己不明白”的杯具中。
现归结以前一直不明白的问题如下:
Q1:为什么要重写equals和HashCode?
Q2:如果重写了上述2个方法,那么究竟是修改了哪个对象的equals和hashCode方法?
Q3:equals方法中的return int 和hashCode方法中的 return boolean 这2个返回值到底是什么意思? 有什么意义? 如果返回值不同会导致什么样的结果?
Q4:equals方法和hashCode方法调用的顺序是怎样的? 以及2个方法被调用的时机? 2个方法会不会有可能不被调用?或者必须2者中的某一个是不是一定会被调用? 等等
通过老大的指点,现通过一个简单案例和图片来回答以上4个问题:
测试案例情形:
将对象 User 放到集合SET里去,然后打印SET集合的对象的数量是多少。
Part 1 代码:
public class User{
public String userName;
public String password;
public User(String userName,String password){
this.userName = userName;
this.password = password;
}
public static void main(String[] arg){
Set<User> users = new HashSet<User>(); //L1
User user=new User("lisa","ddd"); //L2
users.add(user); //L3
// User user1=new User("lisa","ddd"); //L4
// users.add(user1); //L5
System.out.println(“size---->"+users.size()); //L6
}
//重写hashCode和equals方法
public int hashCode(){
system.out.println("fn ----> hashCode");
return 1;
}
public boolean equals(){
system.out.println("fn ----> equals");
return true;
}
}
执行结果:
fn ----> hashCode
size---->1
分析:
L1:首先在内存块堆中给users划分一块空间地址比如a1,再栈中给对象new HashSet划分一块空间比如地址a2。a1指向a2。
L2:同理user--->b1 ;new User("lisa","ddd")---->b2; b1---->b2.
L3: 将user加入到 users中。即将b1 加入到a2中。
在加入的过程中,即调用 hashcode()方法将对象user灌到users中去,而这里的return 1.即理解为set为一栋大楼,而1则为大楼中的第一个房间,而这里即是把user对象放到大楼里面的第一个房间里面去存起。
于是打印了“fn ----> hashCode”。
接着打印 size---->1
但这里为什么只打印了fn ----> hashCode 和 size---->1,而没有打印fn ----> equals 呢?
那就要从hashSet的理解开始了:
首先大家知道hashSet默认是不能放重复的对象到它里面去,hashCode就是负责将对象怎样放在set里面去,而equals()方法就是负责判断你前后放进的对象是否是“重复”的。
那所谓的“重复”又是什么意思呢? 重复就是根据你的业务来判断了。
打个比方:
(1)公安机关认为只要某人的身份证号是一样的,那就是同一个人,不管你是男是女还是李宇春,或者长得美丑或像宋祖德。只要身份证是同一个号码,我公安机关就认定你是同一个人。
(2)但对于普通老百姓就不这样认为了,我不仅要你身份证号码是一样的,还要求你那张脸一定要是李宇春那张脸的,我才认为是同一个人,至少春迷是这样认为的。
所以重复就是不同的业务来定义,对不对。那么就要用到equals 方法来作为人们的判断条件了。因此如果我们要根据不同的业务来判断一个对象是不是同一个对象,就需要我们重写该对象的hashCode和 equals 方法了。对不对。我们这里是判断User对象,因此就重写了User对象的hashCode和 equals 方法.因此这里就回答了Q1和Q2 了。
继续 初始时SET里面为空,因此程序就只负责将user灌到users中,而不用去比较了,因为没有比较的对象啊。所以就没有调用 equals 方法了,因此就没有打印 fn----->equals 了。
感谢--徐老师
继续见 重写equals 和hashCode 探解之洗洗脚(二)
分享到:
相关推荐
以下是对`equals()` 和 `hashCode()` 方法的详细解释及其重写的重要性。 **1. equals() 方法** `equals()` 方法用于比较两个对象是否相等。默认情况下,`equals()` 检查两个对象是否是同一个对象(即内存地址是否...
Java重写equals同时需要重写hashCode的代码说明,以及如何重写hashCode方法,此代码演示按照effective java书籍说明的重写思路。代码中演示了使用集合存储对象,并且对象作为key,需重写equals和hashCode.
重写equals()、hashcode()和compareTo()方法是非常重要的,它可以使我们的程序更加高效、可靠和灵活。在实际开发中,我们需要根据具体情况来决定是否需要重写这些方法,并遵守相关的规则,以避免出现意想不到的结果...
当同时重写 `equals()` 和 `hashCode()` 时,需要注意的一点是,如果 `equals()` 返回true,那么两个对象的 `hashCode()` 必须相等。反之则不一定,因为不同的对象可能会产生相同的哈希码。这就是为什么在设计类时,...
在 TestEqualsHashCode.java 文件中,通常会包含一个示例,演示如何正确地重写 `equals()` 和 `hashCode()` 方法。这个文件可能包含一个自定义类,并展示如何根据类的属性定义这两个方法,以实现特定的比较逻辑。 ...
在实际开发中,我们经常需要重写equals和hashCode方法,以便于正确地比较和存储对象。下面是一个简单的示例代码: public class Student { private String name; private int age; private String QQ; @...
在这个类中,很可能已经重写了`equals()`, `hashCode()` 和 `toString()` 方法,以便更好地处理对象的比较、哈希存储和输出信息。 为了实现`DBObject`类的正确行为,开发者可能考虑了以下几点: 1. 在`equals()`...
例如,public boolean equals(Object o) 是一个正确的重写方法,而 public boolean equals(String o) 是一个重载方法,而不是重写方法。 equals 方法的实现 ------------------------- equals 方法的实现需要遵循...
Java 中 equals、hashcode 和==的区别是 Java 编程语言中一个经常遇到的问题。这三个概念都是用来比较对象的,但是它们之间存在着本质的区别。 首先,==号是Java中的一个运算符,用于比较两个对象的内存地址是否...
如果我们重写了`equals()`方法来基于`name`和`age`判断两个`Coder`对象是否相等,那么我们也应该重写`hashCode()`,使具有相同`name`和`age`的`Coder`对象产生相同的哈希码。通常,`hashCode()`的实现会结合所有参与...
本文介绍了Java语言不直接支持关联数组,可以使用任何对象作为一个索引的数组,但在根Object类中使用 hashCode()方法明确表示期望广泛使用HashMap。理想情况下基于散列的容器提供有效插入和有效检索;直接在对象模式...
Java容器集合(equals和hashCode+基础数据结构+ArrayList+Vector和LinkedList) Java容器集合是Java中的一种基础数据结构,用于存储和管理数据。其中,equals和hashCode方法是Java容器集合中两个非常重要的方法,...
【面试】中提到的几个关键知识点集中在对象比较、equals()和hashCode()方法的使用以及它们之间的关系上。这些概念在Java编程中至关重要,特别是在处理集合类和比较对象时。 1、**hashCode与equals两者之间的关系**...
在 Java 编程语言中,Object 类是所有类的父类,但是在实际开发中,我们往往需要重写 Object 中的 equals 和 hashCode 方法,以便正确地比较对象的逻辑内容,而不是内存地址。下面我们将详细地解释为什么需要重写这...
如果我们只重写了 `equals()` 来比较姓名和年龄,而没有重写 `hashCode()`,那么即使两个 `Person` 实例具有相同的姓名和年龄,它们在哈希表中的位置也可能不同,导致不必要的比较和潜在的性能问题。 总结来说,...
equals 方法和 hashCode 方法是 Java 语言中两个重要的方法,它们都是在 Object 类中定义的。equals 方法用于比较两个对象是否相等,而 hashCode 方法用于返回对象的哈希码。 在 Java 的 Object 类中,equals 方法...
为什么重写equals方法,还必须要重写hashcode方法
在Java编程语言中,`equals()`和`hashCode()`方法是对象的基本组成部分,它们主要用于对象的比较和存储。这两个方法在`java.lang.Object`类中定义,因此所有的Java类都默认继承了这两个方法。然而,根据具体的应用...
如果一个类重写了`equals()`却没有重写`hashCode()`,可能会导致违反JavaDoc的建议,即`equals()`和`hashCode()`必须保持一致。这意味着,如果两个对象`equals()`返回`true`,那么它们的`hashCode()`也必须相同。...
IntelliJ IDEA,作为一款强大的Java集成开发环境,提供了便捷的快捷键功能来帮助开发者快速重写`hashCode()`和`equals()`。 在IDEA中,如果你需要对一个类(比如`Student`类)重写这两个方法,可以遵循以下步骤: ...