Java中equals比较方法使用详解
1、equals方法的背景
在Java中,equals方法是Object类的一个方法,用于比较两个对象是否相等。
Java中有两种比较对象的方法:==运算符和equals方法。
==运算符用于比较两个对象的引用,如果它们指向的是同一个对象,则返回true;而equals方法用于比较两个对象的内容是否相等,当它们的内容相等时,则返回true。因此,equals方法可以用于比较两个值相同的字符串、整型等基本数据类型,或需要通过内容比较才能确定相等的自定义类对象等。
2、equals方法的使用
如何覆盖equals方法
在Java中,一个类如果想要正确地使用equals方法,一定要对该方法进行覆盖。覆盖equals方法的意思是,将equals方法从Object类中继承来的实现替换为自己的实现。如果不覆盖equals方法,则调用该方法时会使用继承的Object类的实现,这种默认实现无法提供正确的比较行为,因为它无法知道哪些属性或状态在两个对象中是必须相同的。
因此,覆盖equals方法的必要性在于提供一个自定义的比较行为,使得该方法可以正确地比较自定义类对象的内容是否相同。而覆盖equals方法的步骤如下:
1)确定对象相等的条件;
2)覆盖equals方法,实现对象相等的比较逻辑;
3)同时覆盖hashCode方法,确保相等的对象具有相等的hashCode值。
equals方法的实现
在重写equals方法时应该遵循以下的通用标准:
1)自反性:对于任何非null的引用值x,x.equals(x)应该返回true;
2)对称性:对于任何非null的引用值x和y,如果x.equals(y)返回true,则y.equals(x)也应该返回true;
3)传递性:对于任何非null的引用值x、y和z,如果x.equals(y)返回true,y.equals(z)也返回true,那么x.equals(z)也应该返回true;
4)一致性:对于任何非null的引用值x和y,如果用于equals比较的对象信息没有发生变化,那么无论进行多少次比较,都应该返回true或false;
5)非空性:对于任何非null的引用值x,x.equals(null)应该返回false。
下面是一个重写equals方法的例子,假设我们有一个自定义的EqualsDemo类:
public class EqualsDemo { private String name; private int age; private double salary; //构造函数和getter/setter方法 // 重写equals方法 public boolean equals(Object obj) { if (obj == this) { // 如果是同一对象,返回true return true; } if (!(obj instanceof EqualsDemo)) { // 如果obj不是Employee类对象,返回false return false; } EqualsDemo equalsDemo = (EqualsDemo)obj; // 强制转换为Employee类对象 return equalsDemo.name.equals(this.name) && equalsDemo.age == this.age && equalsDemo.salary == this.salary; } // 重写hashCode方法 public int hashCode() { int result = 17; result = 31 * result + name.hashCode(); result = 31 * result + age; long temp = Double.doubleToLongBits(salary); result = 31 * result + (int)(temp ^ (temp >>> 32)); return result; } }
在这个例子中,EqualsDemo类重写了equals方法,比较了该类的三个属性:name,age和salary。如果两个EqualsDemo对象的这三个属性都相等,则这两个EqualsDemo对象相等。同时,EqualsDemo类也重写了hashCode方法,根据该类的属性计算了hashCode值。
3、equals方法的使用注意事项
在使用equals方法时,需要遵循以下注意事项:
1)永远不要使用equals方法比较对象的类型。如果没有覆盖equals方法,则Object.equals(Object obj)只有在obj和本身引用同一个对象时才返回true;如果覆盖了equals方法,则equals(Object obj)所接收的参数类型必须与本身的类型相同或可以强制转换成本身类型。
2)永远不要使用equals方法比较字符串常量。在Java中,字符串常量是共享的,如果用equals方法比较两个字符串常量,可能会导致不正确的结果。
3)永远不要使用equals方法比较两个浮点型或双精度型的值。由于浮点数在计算机内部只能表示近似值,所以可能会导致不正确的结果。
4、equals方法的相关问题
1. equals方法与“==”有何区别?
在Java中,==运算符和equals方法都可以用于比较两个对象。它们之间的区别在于:
==运算符用于比较两个对象的引用,如果它们指向的是同一个对象,则返回true;
equals方法用于比较两个对象的内容是否相等,当它们的内容相等时,则返回true。
例如:
Integer a = new Integer(10); Integer b = new Integer(10); System.out.println(a == b); //false System.out.println(a.equals(b)); //true
在这个例子中,a和b是两个不同的Integer对象,虽然它们的值相同,但是它们指向的是不同的对象,因此使用==运算符比较时返回false。但是,因为它们的值相同,使用equals方法比较时返回true。
2.equals方法与hashCode方法有何联系?
在Java中,每个对象都有一个默认的hashCode值,该值是一种与该对象有关的整数,并且具有以下特性:
1)如果两个对象相等,则它们的hashCode值一定相等;
2)如果两个对象的hashCode值相等,则它们不一定相等。
因此,在覆盖equals方法时,必须同时覆盖hashCode方法,以保证相等的对象具有相等的hashCode值。hashCode方法返回的值应该根据equals方法比较的对象信息计算得出,具体实现方式可以借鉴上面的例子。
3. equal方法的效率问题
在Java中,equals方法的执行效率可能会受到多种因素的影响,例如equals方法的实现逻辑、对象属性的数量和类型等。因此,在比较大规模的对象时,equals方法的效率可能会显著降低。
为了提高equals方法的执行效率,可以考虑以下几种方法:
1)先比较两个对象的hashCode值,如果它们的hashCode值不同,则这两个对象不相等,可以直接返回false;
2)将equals方法的比较顺序调整,将属性值变化频率低的属性放在前面比较;
3)使用缓存,将对象的hashCode值缓存起来,避免重复计算。
补充知识:重写equals方法练习
package object; /* 判断两个person对象的内容是否相等 如果两个person对象的各个属性值都一样,则返回true,反之返回false */ public class EqualsExercise { public static void main(String[] args) { Person person1 = new Person("jack", 10, '男'); Person person2 = new Person("jack", 10, '男'); System.out.println(person1.equals(person2)); //输出结果是true } } class Person { private String name; private int age; private char gender; //重写Object的equals方法 public boolean equals(Object obj) { //如果比较的两个对象是同一个对象,则直接返回true if (this == obj){ //this就代表调用equals方法的那个对象,obj就是方法里面的实参 return true; } //类型判断 if (obj instanceof Person){ //obj是Person,我们才比较 //进行 向下转型(即obj转成Person); 因为我需要得到obj的各个属性,如果不转型,拿不到 Person p = (Person) obj; return this.name.equals(p.name) && this.age == p.age && this.gender == p.gender; } //如果不是person,则直接返回false;总不能拿一个人跟一个狗比 return false; } public Person(String name, int age, char gender) { this.name = name; this.age = age; this.gender = gender; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public char getGender() { return gender; } public void setGender(char gender) { this.gender = gender; } }
Tips:
instanceof的用法:result = object instanceof class
instanceof左边是对象,右边是类;当对象是右边类或子类所创建对象时,返回true;否则,返false。
总结
到此这篇关于Java中equals比较方法使用详解的文章就介绍到这了,更多相关Java equals比较方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
ArrayList和LinkedList区别及使用场景代码解析
这篇文章主要介绍了ArrayList和LinkedList区别及使用场景代码解析,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下2018-01-01
最新评论