当前位置:首页 > 安卓源码 > 技术博客 >

java中重写equals时必须重写hashCode方法?

时间:2018-12-14 16:09 来源:互联网 作者:源码搜藏 浏览: 收藏 挑错 推荐 打印

java中重写equals时必须重写hashCode方法? hashCode:是一个native方法,返回的是对象的内存地址, equals:对于基本数据类型,==比较的是两个变量的值。对于引用对象,==比较的是两个对象的地址。 接下来我们看下hashCode的注释 1.在 Java 应用程序执行期间

java中重写equals时必须重写hashCode方法?

hashCode:是一个native方法,返回的是对象的内存地址,

equals:对于基本数据类型,==比较的是两个变量的值。对于引用对象,==比较的是两个对象的地址。

接下来我们看下hashCode的注释

1.在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。
 从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。 
2.如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。 
3.如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么两个对象不一定必须产生不同的整数结果。
 但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。

从hashCode的注释中我们看到,hashCode方法在定义时做出了一些常规协定,即

1,当obj1.equals(obj2) 为 true 时,obj1.hashCode() == obj2.hashCode()

2,当obj1.equals(obj2) 为 false 时,obj1.hashCode() != obj2.hashCode()

hashcode是用于散列数据的快速存取,如利用HashSet/HashMap/Hashtable类来存储数据时,都是根据存储对象的hashcode值来进行判断是否相同的。如果我们将对象的equals方法重写而不重写hashcode,当我们再次new一个新的对象的时候,equals方法返回的是true,但是hashCode方法返回的就不一样了,如果需要将这些对象存储到结合中(比如:Set,Map ...)的时候就违背了原有集合的原则,下面让我们通过一段代码看下。

/**
 * @see Person
 * @param args
 */
 public static void main(String[] args)
 {
 HashMap<Person, Integer> map = new HashMap<Person, Integer>();
 Person p = new Person("jack",22,"男");
 Person p1 = new Person("jack",22,"男");
 System.out.println("p的hashCode:"+p.hashCode());
 System.out.println("p1的hashCode:"+p1.hashCode());
 System.out.println(p.equals(p1));
 System.out.println(p == p1);
 map.put(p,888);
 map.put(p1,888);
 map.forEach((key,val)->{
 System.out.println(key);
 System.out.println(val);
 });
 }

equals和hashCode方法的都不重写

public class Person
{
 private String name;
 private int age;
 private String sex;
 Person(String name,int age,String sex){
 this.name = name;
 this.age = age;
 this.sex = sex;
 }
}
p的hashCode:356573597
p1的hashCode:1735600054
false
false
com.blueskyli.练习.Person@677327b6
888
com.blueskyli.练习.Person@1540e19d
888

只重写equals方法

public class Person
{
 private String name;
 private int age;
 private String sex;
 Person(String name,int age,String sex){
 this.name = name;
 this.age = age;
 this.sex = sex;
 }
 @Override public boolean equals(Object obj)
 {
 if(obj instanceof Person){
 Person person = (Person)obj;
 return name.equals(person.name);
 }
 return super.equals(obj);
 }
}
p的hashCode:356573597
p1的hashCode:1735600054
true
false
com.blueskyli.练习.Person@677327b6
888
com.blueskyli.练习.Person@1540e19d
888

equals和hashCode方法都重写

public class Person
{
 private String name;
 private int age;
 private String sex;
 Person(String name,int age,String sex){
 this.name = name;
 this.age = age;
 this.sex = sex;
 }
 @Override public boolean equals(Object obj)
 {
 if(obj instanceof Person){
 Person person = (Person)obj;
 return name.equals(person.name);
 }
 return super.equals(obj);
 }
 @Override public int hashCode()
 {
 return name.hashCode();
 }
}
p的hashCode:3254239
p1的hashCode:3254239
true
false
com.blueskyli.练习.Person@31a7df
888

我们知道map是不允许存在相同的key的,由上面的代码可以知道,如果不重写equals和hashCode方法的话会使得你在使用map的时候出现与预期不一样的结果,具体equals和hashCode如何重写,里面的逻辑如何实现需要根据现实当中的业务来规定。

总结:

1,两个对象,用==比较比较的是地址,需采用equals方法(可根据需求重写)比较。

2,重写equals()方法就重写hashCode()方法。

3,一般相等的对象都规定有相同的hashCode。

4,String类重写了equals和hashCode方法,比较的是值。

5,重写hashcode方法为了将数据存入HashSet/HashMap/Hashtable(可以参考源码有助于理解)类时进行比较

java中重写equals时必须重写hashCode方法? 转载https://www.codesocang.com/appboke/39133.html

技术博客阅读排行

最新文章