最近重新研究java基础, 看到了java中Object类的equals()方法。java中比较两个对象相等性有两个方法,一个是==, 另一个是俄quals()方法(当然基本类型不能直接调用,需要包装类包装)。常问的问题就是这两个方法的区别,很多人会说出好几条区别,比如==比的是对象的引用,equals比较的是对象的值。其实这是一种误解,看看Object类中equals()方法的源代码。
public boolean equals(Object obj) {
return (this == obj);
}
就这么简单, 原来equals调用的就是==。那么上述的论断来源于哪儿呢,其实很多人都说得是String类重写的equals方法。
重写equals很简单,以下举一个简单例子来演示一下
class Person{
private String name;
private int age;
public Person(String name, int age){
this.name = name;
this.age = age;
}
// 省略getter/setter方法
}
然后我们就可以来试验equals和==了
Person p1 = new Person("xg", 29);
Person p2 = new Person("xg", 29);
System.out.println(p1 == p2);
System.out.println(p1.equals(p2));
结果都是false,显然。
那么接下来就是要重写equals了。目前流行的写法如下:
public boolean equals(Object obj){
if (obj == null) {
return false;
}else if(!(obj instanceof Person)){
return false;
}
Person p = (Person)obj;
if(this.getName().equals(p.getName()) && this.getAge() == p.getAge()){
return true;
}else{
return false;
}
}
思路很清晰,不说了
不过我更喜欢另一种简单的写法
public boolean equals(Object obj){
if (obj instanceof Person){
return this.getName().equals(((Person)obj).getName())
&& this.getAge() == ((Person)obj).getAge();
}else {
return false;
}
}
这种写法更加简洁,功能是一样的。
再试验上面的例子
Person p1 = new Person("xg", 29);
Person p2 = new Person("xg", 29);
System.out.println(p1 == p2);
System.out.println(p1.equals(p2));
返回false,true,因为equals被重写了。
到此似乎已经很完美了,其实不然,看到下面的结果就会发现。
Map<Person, String> map = new HashMap<Person, String>();
map.put(new Person("xg", 28), "Person1");
System.out.println(map.get(new Person("xg", 28)));
本以为应该返回Person1的字符串,确返回了一个null,这是怎么回事呢?
让我们看看HashMap中get方法是怎么实现的
public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode()); // 获得参数key的hashCode
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) // 比较hashCode,如果相同则返回值
return e.value;
}
return null; // 否则返回null
}
那我们就看一看hashCode吧。
Person p1 = new Person("xg", 29);
Person p2 = new Person("xg", 29);
System.out.println(p1.hashCode() + "----" + p2.hashCode());
我们看到两个完全不同的值
那么好了,根据java的Object规范,当两个对象的equals方法返回true时,这两个对象的hashCode必须返回同样的值。为什么要这么规定呢?相信原因你已经知道了,因为一旦不同,那么这个对象在与HashMap,Hashtable,HashSet一起使用时,一定要有问题。(想象一下如果String类没有重写HashCode那将多么可怕)
那么如何重写hashCode方法呢,这个难度就很大了,目前已知的是,如果能保持不同的对象,返回不同的hashCode值,这就是最好的。原理参见hash算法的实现。
接下来就重写一个
public int hashCode(){
return this.name.length()*37 + this.age;
}
再试验一下例子
Map<Person, String> map = new HashMap<Person, String>();
map.put(new Person("xg", 28), "Person1");
System.out.println(map.get(new Person("xg", 28)));
OK了,结果是Person1。
结论:重写equals一定要重写hashCode。
分享到:
相关推荐
在 Java 中,equals 方法是一个非常重要的方法,它用于判断两个对象是否相等,而不是判断两个对象的引用是否相同。在 Object 基类中,equals 方法的实现是使用“==”操作符来比较对象的引用,但是这并不满足实际需求...
Java重写equals同时需要重写hashCode的代码说明,以及如何重写hashCode方法,此代码演示按照effective java书籍说明的重写思路。代码中演示了使用集合存储对象,并且对象作为key,需重写equals和hashCode.
`equals`方法是Java语言中Object类的一个重要成员方法,其默认实现是比较两个对象的内存地址是否相同(即是否为同一个对象)。为了使对象之间能够基于内容进行比较,通常需要在具体的类中重写`equals`方法。 #### ...
在Java编程语言中,`equals()` 和 `hashCode()` 方法是对象的基本组成部分,它们在很多场景下都发挥着至关重要的作用。这两个方法与对象的相等性比较和哈希表(如HashMap、HashSet)的运作紧密相关。这篇博客将深入...
总的来说,理解并正确地重写 `equals()` 和 `hashCode()` 方法是Java编程中的基础技能,它有助于确保对象的比较和集合操作的正确性。在开发过程中,要时刻注意这两个方法的正确实现,以提高代码质量和可维护性。
Java中equals()方法重写实现代码详解 Java中equals()方法是Object类中定义的,作为所有类的父类,任何类都隐含地继承了该方法。 equals()方法用于判断两个对象的内容是否相同,如果没有重写该方法的类,需要重写该...
Java 对象的toString和equals方法重写 在 Java 中,每个对象都继承自 Object 类,而 Object 类中定义了两个重要的方法:toString() 和 equals()。这两个方法都是非常重要的,它们分别用于对象的字符串表示和对象...
关于 Java 中重写 equals 方法的种种坑 Java 中的 equals 方法是一种用于比较对象是否相等的方法,它是 Object 类中的一个方法。然而,重写 equals 方法并不是一件简单的事情,因为它需要遵守一些约定,否则可能会...
在Java编程语言中,了解如何正确使用`==`和`equals()`方法是非常关键的,因为它们在比较对象和基本类型时有不同的行为。下面将详细解释这两个方法的工作原理、使用场景以及一些常见误区。 首先,`==`运算符主要用于...
Java 中关于 == 和 equal 的区别 及其 equals() 方法重写 Java 语言是 Sun 公司的开发成果,其主要特点是可以执行强,与平台的无关性使其实用性更强。但是 Java 中的 == 与 equal 是有区别的。 == 操作符是 Java ...
Java中的equals方法重写介绍 Java中的equals方法是一个非常重要的方法,它用于判断两个对象是否相等。在Java中,所有的对象都继承自Object类,而Object类中有一个equals方法,该方法用于判断两个对象是否相等。但是...
深入解析Java对象的equals()和hashCode()的使用 在Java语言中,equals()和hashCode()两个函数的使用是紧密配合的,你要是自己设计其中一个,就要设计另外一个。在多数情况下,这两个函数是不用考虑的,直接使用它们...
在Java编程语言中,`equals()` 和 `hashCode()` 是两个非常重要的方法,它们主要用于比较对象的平等性以及在散列数据结构(如 `HashMap`、`HashSet` 等)中的对象定位。当我们创建自定义类时,有时需要根据业务需求...
在 Java 中,重写 equals() 方法和 hashCode() 方法是非常重要的,它们可以确保对象的比较和标识正确。如果我们违反了这两个方法的规则,那么可能会产生理解的不一致。因此,在编写 Java 代码时,需要严格遵守这两个...
在Java编程语言中,`equals()`和`hashCode()`方法是对象的基本组成部分,它们主要用于对象的比较和存储。这两个方法在`java.lang.Object`类中定义,因此所有的Java类都默认继承了这两个方法。然而,根据具体的应用...
这涉及到对Java对象模型的理解,以及如何根据对象的业务逻辑来定义“相等”的概念。通过遵循API规范和良好的编码习惯,我们可以确保`equals`方法的行为符合预期,避免出现类似上面例子中的问题。
equals方法是Java中Object类的一个方法,用于比较两个对象的内存地址是否相等。其源码如下: public boolean equals(Object paramObject){ return(this == paramObject); } 从源码中可以看到,equals方法是用来...
在Java编程语言中,"方法重写equals"和"多态"是两个核心概念,尤其对于面向对象的设计和实现至关重要。下面将详细解释这两个概念及其相互关系。 **方法重写equals()** 在Java中,`equals()`方法是Object类的一个...
equals 方法是 Java 中一个非常重要的方法,因为它是 Object 类中的一个基本方法,每个对象都可以根据自己的需求来重写这个方法。 三、hashCode 和 equals 方法的关系 hashCode 和 equals 方法之间存在着紧密的...
在Java编程语言中,`equals()`方法和`==`运算符是两个经常被用来比较对象是否相等的关键概念。理解它们的区别和用法对于任何Java开发者来说都至关重要,特别是对于那些正在积累Java开发经验的人来说。 首先,让我们...