Java如何比较两个对象

1 Java如何比较两个对象的介绍

Java Object类是所有Java类的超类。默认情况下,所有Java类都实现Object类。Java Object类提供了两个重要的方法来比较Java中的两个对象,即equals() 和hashCode() 方法。在本节中,我们将学习equals() 和hashCode() 方法的工作方式。除此之外,我们还将学习如何将Java中的两个对象与适当的示例进行比较。

Java提供了Object类的两种方法来比较对象,如下所示:

  • Java equals() 方法
  • Java hashCode() 方法

2 Java equals()方法

2.1 Java equals()方法的介绍

Object类的equals() 方法比较两个对象的相等性。如果两个对象共享相同的内存地址,则它们将相等。

语法:

public boolean equals(Object obj)  

该方法将参考对象解析为参数。如果对象相等,则返回true,否则返回false。

一个对象也可能等于另一个给定的对象,然后equals() 方法遵循等价关系来比较这些对象。

  • 自反:如果x是非空引用,则x.equals(x) 的调用必须返回true。
  • 对称:如果两个非空引用是X和Y,x.equals(Y) 将返回真当且仅当y.equals(x) 返回真。
  • 传递:如果三个非空引用是X,Y和Z,x.equals(z) 也将返回真,如果x.equals(Y) 和y.equals(Z) 都返回真。
  • 一致:如果两个非null引用分别是x和y,则x.equals(y) 的多次调用将不断返回true或false。它不提供比较中使用的任何信息。
  • 对于任何非null引用x,x.equals(null) 返回false。

简而言之,对于任何非空引用,例如x和y,当且仅当两个引用都引用相同的对象时,它才返回true。

注意:当我们重写equals() 方法时,有必要重写hashCode() 方法。覆盖遵循hashCode() 方法的约定,该约定指出,相等的对象必须具有相等的哈希码。

2.2 Java equals()方法案例

在下面的示例中,我们创建了Double和Long类的构造函数,并传递了相应的值作为分别存储在其对象中的参数。

之后,在第一个println语句中,我们调用了equals() 方法,并将对象y解析为比较对象x和y的参数。它返回false,因为x持有双精度值,而y持有不相等的长值。

同样,在第二个println语句中,我们调用了equals() 方法并解析与Double类的构造函数中相同的值。它返回true,因为双精度类(即x)的对象具有与equals() 方法中传递的值相同的值。

/**
 * 一点教程网: http://www.yiidian.com
 */
public class ObjectComparisonExample  
{  
public static void main(String[] args)   
{  
//creating constructor of the Double class   
Double x = new Double(123.45555);  
//creating constructor of the Long class   
Long y = new Long(9887544);  
//invoking the equals() method   
System.out.println("Objects are not equal, hence it returns " + x.equals(y));  
System.out.println("Objects are equal, hence it returns " + x.equals(123.45555));  
}  
}  

输出结果为:

Objects are not equal, hence it returns false
Objects are equal, hence it returns true

3 ==运算符和equal()方法之间的区别

在Java中,==运算符比较两个引用是否相同。而equals() 方法比较两个对象。

当对象具有相同的状态(通常是比较变量)时,它们是相等的。对象共享类标识时,它们是相同的。

例如,表达式obj1 == obj2测试身份,而不是相等性。而表达式obj1.equals(obj2) 比较相等。

4 Java hashCode()方法

4.1 Java hashCode()方法的介绍

在Java中,哈希码是32位带符号整数值。它是JVM提供给Java对象的唯一ID 。每个Java对象都与哈希码相关联。哈希码由基于哈希的数据结构(例如HashTable,HashSet等)管理。

注意:当我们覆盖equals() 方法时,也必须覆盖hashCode() 方法。

语法:

public int hashCode()  

它返回对象的随机生成的哈希码值,该值对于每个实例都是唯一的。在程序的多次执行过程中,随机生成的值可能会更改。

hashCode的一般约定为:

  • 在应用程序执行过程中多次调用它时,hashCode() 方法将始终返回相同的哈希码(整数值)。请注意,不应修改该对象。
  • 如果根据equals() 方法两个对象相等,则在这两个对象上调用hashCode()方法必须产生相同的整数值。
  • 如果两个对象根据equals() 方法不相等,则不必这样做,则在这两个对象上调用hashCode() 方法可能会产生不同的整数值。这意味着它可以为两个对象产生相同的哈希码。

4.2 Java hashCode()方法案例

在以下示例中,我们创建了两个类Employee.java和HashCodeExample.java。

在Employee类中,我们定义了两个类型为int的regno和类型为String的名称的字段。之后,我们创建了Employee类的构造函数,并将这两个字段作为参数传递。

为了进行对象比较,我们创建了一个单独的名为HashCodeExample的类。在此类中,我们创建了Employee类的两个实例,即emp1和emp2。之后,我们使用对象调用了hashCode() 方法。我们已经将哈希码值分别存储在变量a和b中。

Employee.java:

/**
 * 一点教程网: http://www.yiidian.com
 */
public class Employee   
{  
private int regno;  
private String name;  
//constructor of Employee class  
public Employee(int regno, String name)   
{  
this.name = name;  
this.regno = regno;  
}  
public int getRegno()   
{  
return regno;  
}  
public void setRegno(int Regno)   
{  
this.regno = regno;  
}  
public String getName()   
{  
return name;  
}  
public void setName(String name)   
{  
this.name = name;  
}  
}

HashCodeExample.java:

/**
 * 一点教程网: http://www.yiidian.com
 */
public class HashcodeExample  
{  
public static void main(String[] args)   
{  
//creating two instances of the Employee class  
Employee emp1 = new Employee(918, "Maria");  
Employee emp2 = new Employee(918, "Maria");  
//invoking hashCode() method  
int a=emp1.hashCode();  
int b=emp2.hashCode();  
System.out.println("hashcode of emp1 = " + a);  
System.out.println("hashcode of emp2 = " + b);  
System.out.println("Comparing objects emp1 and emp2 = " + emp1.equals(emp2));  
}  
}  

输出结果为:

hashcode of emp1 = 2398801145
hashcode of emp2 = 1852349007
Comparing objects emp1 and emp2 = false

5 覆盖equals()方法

如果我们要提供自己的实现,可以按以下方式重写equals() 方法。

//overriding equals() method  
@Override  
public boolean equals(Object obj)   
{  
if (obj == null)   
return false;  
if (obj == this)  
return true;  
return this.getRegno() == ((Employee) obj). getRegno();  
}  

上面的代码片段显示,如果两个雇员存储在相同的内存地址中或具有相同的regno,则它们将相等。当我们使用上述代码片段运行程序(HashCodeExample.java)时,将获得以下输出。

hashcode of emp1 = 2032578917
hashcode of emp2 = 1531485190
Comparing objects emp1 and emp2 = true

 

热门文章

优秀文章