发布时间:2018-08-03作者:laosun阅读(1905)
Java 重写equals() 和 hashCode()
java的==和equals的对比方式。
1、基本数据类型比较
==和Equals都比较两个值是否相等。相等为true 否则为false;
2、引用对象比较
==和Equals都是比较栈内存中的地址是否相等 。相等为true 否则为false;
下边来看个例子:
package com.sunjs.java; public class EqualsTest { public static void main(String[] args) { System.out.println("================基本数据类型比较==============="); //在str1指向常量池中的abc,str2也指向了常量池中的abc String str1 = "abc"; String str2 = "abc"; System.out.println("基本数据类型==比较:"+ (str1==str2)); System.out.println("基本数据类型equals比较:"+ (str1.equals(str2))); System.out.println("\n================引用对象比较 1==============="); //new 了两次,相当于在堆内存中创建了两个不同的对象,所以a和b两个引用分别指向了两个对象 Integer a = new Integer(1); Integer b = new Integer(1); System.out.println("Integer引用对象==比较:"+ (a == b)); //a和b指向了两个对象,为什么equals对比还是一样的呢,具体请查看Integer类的equals方法和hashcode方法就清楚原因了 System.out.println("Integer引用对象equals比较:"+ (a.equals(b))); System.out.println("\n================引用对象比较 2==============="); Users userA = new Users("sun", 18); Users userB = new Users("sun", 18); //从这里打印hashcode可以得出,两个引用指向了两个不同的堆对象,所以hashcode也不一样 //这里呢,我们需要知道一点,equals()相同时 hashcode 必须相同, 但是hashcode相同并不一定eqauls相同 //具体为什么呢,自己去百度、google一下。 System.out.println(userA.hashCode()+" == "+userB.hashCode()); //因为userA和userB是两个不同的引用,也指向了两个不同的堆对象,所以他们==必然是不同的 System.out.println("引用对象==比较:"+ (userA == userB)); //同上,引用不同,对比自然不同 System.out.println("引用对象equals比较:"+ (userA.equals(userB))); } } class Users { private String name; private int age; public Users() { super(); } public Users(String name, int age) { super(); this.name = name; this.age = age; } 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; } }
打印结果:
================基本数据类型比较=============== 基本数据类型==比较:true 基本数据类型equals比较:true ================引用对象比较 1=============== Integer引用对象==比较:false Integer引用对象equals比较:true ================引用对象比较 2=============== 204349222 == 231685785 引用对象==比较:false 引用对象equals比较:false
下边来演示一下重写equals方法和hashcode方法的三种方式:
1:我们使用17和31散列码,这种想法来自于一本经典的java书籍《Effective Java》。这本书已经出到第三版了,不过是英文的,中文的只有第二版可以看。 还有一本书比较经典,也推荐大家看看,博主现在正在细看《Java编程思想》,也就是Thinking in Java,这本书第四版已经出来好几年了。
package com.sunjs.java; public class EqualsTest { public static void main(String[] args) { System.out.println("================引用对象比较(重写equals和hashcode方法 1 )================"); //创建Mac对象,并且重写equals和hashcode方法 //虽然从理论上来说重写equals方法就能达到我们想要的结果,但是这样不利于哈希表的性能,也不符合hashcode的规则 Mac mac1 = new Mac("13寸", 14500.00, 11); Mac mac2 = new Mac("13寸", 14500.00, 11); System.out.println(mac1.hashCode()+" == "+mac2.hashCode()); System.out.println("重写-引用对象==比较:"+ (mac1 == mac2)); //很明显重新后equals比较是样的。 System.out.println("重写-引用对象equals比较:"+ (mac1.equals(mac2))); } } class Mac{ private String name; private Double money; private Integer num; public Mac() { super(); } public Mac(String name, Double money, Integer num) { super(); this.name = name; this.money = money; this.num = num; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getMoney() { return money; } public void setMoney(Double money) { this.money = money; } public Integer getNum() { return num; } public void setNum(Integer num) { this.num = num; } //重写equals方法 @Override public boolean equals(Object obj) { if(obj==this){ return true; } if(!(obj instanceof Mac)){ return false; } Mac mac = (Mac)obj; return mac.getName().equals(name) && mac.getMoney().equals(money) && mac.getNum()==num; } /** * 重写hashcode方法 * 这种17和31散列码的想法来自经典的Java书籍——《Effective Java》第九条 * @author sun * @return */ @Override public int hashCode() { int result = 17; result = 31 * result + name.hashCode(); result = 31 * result + money.hashCode(); result = 31 * result + num; return result; } }
打印结果:
================引用对象比较(重写equals和hashcode方法 1 )================ -588737296 == -588737296 重写-引用对象==比较:false 重写-引用对象equals比较:true
2:对于JDK7及更新版本,你可以是使用java.util.Objects 来重写 equals 和 hashCode 方法,代码如下
这里我就只贴重要的代码(equals和hashcode):
@Override public boolean equals(Object obj) { if(obj==this){ return true; } if(!(obj instanceof Mac)){ return false; } Mac mac = (Mac)obj; return Objects.equals(mac.getName(), name) && Objects.equals(mac.getMoney(), money) && mac.getNum()==num; } @Override public int hashCode() { return Objects.hash(name, money, num); }
3:使用Apache Commons Lang 包中的 EqualsBuilder 和HashCodeBuilder 方法
使用此方法导jar包
@Override public boolean equals(Object obj) { if(obj==this){ return true; } if(!(obj instanceof Mac)){ return false; } Mac mac = (Mac)obj; return new EqualsBuilder().append(mac.getName(), name).append(mac.getMoney(), money).append(mac.getNum(), num).isEquals(); } @Override public int hashCode() { return new HashCodeBuilder(17, 37).append(name).append(money).append(num).toHashCode(); }
其实后两种都是对于17和31散列码思想的封装实现!
版权属于: 技术客
原文地址: https://www.sunjs.com/article/detail/090373f4f96c4c7eae0040ea820de63a.html
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。