很多人问复写equals一定要复写hashCode方法吗?
我们在判断对象是否相等的时候往往会用的equals方法,根据对象的某个值是否相同来决定对象是否相等,所以这里我们需要复写equals方法。例如下面的代码:
public class Persion { PRivate Integer id; private Integer age; private String name; @Override public boolean equals(Object obj) { if(this.getClass()==obj.getClass()){ return id.equals(((Persion)obj).id); } return false; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; }} public static void main(String[] args) { Persion p1 = new Persion(); p1.setId(1); p1.setAge(1); p1.setName("张三"); Persion p2 = new Persion(); p2.setId(1); p2.setAge(2); p2.setName("李四"); System.out.println(p1.equals(p2)); } //返回的是true那么问题来了,既然equals可以实现功能我们为什么还要复写hascCode,接着往下看:
@Test public void testHashCode(){ HashMap<Persion, String> map1 = new HashMap<>(); Persion p1 = new Persion(); p1.setId(1); p1.setAge(1); p1.setName("张三"); map1.put(p1, "测试"); Persion p2 = new Persion(); p2.setId(1); p2.setAge(2); p2.setName("李四"); System.out.println(map1.containsKey(p2)); } //返回的是false因为hashMap(或是hashSet)的containsKey方法涉及到了hashCode的操作,
public boolean containsKey(Object paramObject) { return getNode(hash(paramObject), paramObject) != null; } static final int hash(Object paramObject) { int i; return paramObject == null ? 0 : (i = paramObject.hashCode()) ^ i >>> 16; }这里如果想返回true,必须equals与hashCode同时返回true才行。
我们复写Persion的hashCode方法
@Override public int hashCode() { return id.hashCode(); }再执行测试用例就可以返回true.
总结:理论上没有涉及到hashCode的操作,我们复写equals方法就可以,但是,java规范约定,如果重写equals方法,那也要重写hashCode方法,使equals为真的情况,hashCode的值也是相同的,所以我们在复写的equals的时候尽量也复写hashCode,保险一点。
补充:String与Integer的hashCode是根据他们包内的值来计算生成的,如果两个值相等则hashCode相等。
String a = "张三"; String b = "张三"; System.out.println(a.hashCode()==b.hashCode()); Integer c =1; Integer d =1; System.out.println(c.hashCode()==d.hashCode());新闻热点
疑难解答