这些方法可以在 Object 类中找到,因此可用于所有 java 类。使用这两种方法,可以从 Hashtable、HashMap 或 HashSet 中存储或检索对象。
hashcode()
您可能知道,如果您将条目放入 HashMap,首先计算哈希码,然后此哈希码用于查找存储桶(索引),该条目将存储在hashMap 中。如果你不覆盖 hashcode 方法,它将返回内存地址的整数表示。
当你想定义两个对象之间的相等性时,你必须重写 equals 方法。如果您不覆盖此方法,它将检查引用相等(==),即两个引用是否引用相同的对象
您不必总是重写这些方法,但是假设您想根据名称定义国家对象的相等性,那么您需要重写 equals 方法,如果您要重写 equals 方法,您也应该重写 hashcode 方法。下面的例子将清楚。
让我们借助示例来看看。我们有一个名为 Country 的类
1.Country.java
package org.arpit.java2blog; public class Country { String name; long population; public String getName() { return name; } public void setName(String name) { this.name = name; } public long getPopulation() { return population; } public void setPopulation(long population) { this.population = population; } }
这个国家类有两个基本属性——名称和人口。
现在创建一个名为“EqualityCheckMain.java”的类
package org.arpit.java2blog; public class EqualityCheckMain { /** * @author arpit mandliya */ public static void main(String[] args) { Country india1=new Country(); india1.setName("India"); Country india2=new Country(); india2.setName("India"); System.out.println("Is india1 is equal to india2:" +india1.equals(india2)); } }
当你运行上面的程序时,你会得到以下输出
Is india1 is equal to india2:false
在上面的程序中,我们创建了两个不同的对象并将它们的名称属性设置为“india”。
因为引用 india1 和 india2 都指向不同的对象,所以默认实现 equals 检查 ==,equals 方法返回 false。在现实生活中,它应该返回 true,因为没有两个国家可以有相同的名称。
如果两个国家的名称相同,现在让我们覆盖 equals 并返回 true。
将此方法添加到上述国家/地区类:
@Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Country other = (Country) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; }
现在再次运行 EqualityCheckMain.java
您将获得以下输出:
Is india1 is equal to india2:true
现在这是因为如果两个国家名称相同,则覆盖的 equals 方法返回 true。 这里要记住一件事,equals 方法的签名应该与上面相同。
在这里,我们将使用 Country 类对象作为键,并将其大写名称(字符串)作为 HashMap 中的值。
package org.arpit.java2blog; import java.util.HashMap; import java.util.Iterator; public class HashMapEqualityCheckMain { /** * @author Arpit Mandliya */ public static void main(String[] args) { HashMap<Country,String> countryCapitalMap=new HashMap<Country,String>(); Country india1=new Country(); india1.setName("India"); Country india2=new Country(); india2.setName("India"); countryCapitalMap.put(india1, "Delhi"); countryCapitalMap.put(india2, "Delhi"); Iterator countryCapitalIter=countryCapitalMap.keySet().iterator(); while(countryCapitalIter.hasNext()) { Country countryObj=countryCapitalIter.next(); String capital=countryCapitalMap.get(countryObj); System.out.println("Capital of "+ countryObj.getName()+"----"+capital); } } }
当您运行上述程序时,您将看到以下输出:
Capital of India----Delhi Capital of India----Delhi
现在您一定想知道即使两个对象相等,为什么 HashMap 包含两个键值对而不是一个。这是因为 First HashMap 使用哈希码来查找该键对象的存储桶,如果哈希码相同,则仅检查 equals 方法,因为以上两个国家对象的哈希码使用默认的哈希码方法,两者都有不同的内存地址,因此有不同的哈希码。
现在让我们覆盖哈希码方法。将以下方法添加到 Country 类
@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; }
现在再次运行 HashMapEqualityCheckMain.java
您将看到以下输出:
Capital of India----Delhi
所以现在上面两个对象 india1 和 india2 的哈希码是相同的,所以两者都将指向同一个桶,现在将使用 equals 方法比较它们,这将返回 true。 这就是 java doc 说“如果你覆盖 equals() 方法,那么你必须覆盖 hashCode() 方法”的原因
equals 方法在非空对象引用上实现等价关系:
原文链接:https://codingdict.com/