有这样一个再简单不过的java beanpackage com.crazycoder2010.equal; public class EqualBean { private int id; private String name; public EqualBean(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
让后我们写个测试程序,看看运行结果是什么package com.crazycoder2010.equal; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class EqualTest { public static void main(String[] args) { List<EqualBean> equalBeans = new ArrayList<EqualBean>(); for(int i = 0; i < 2; i++){ equalBeans.add(new EqualBean(1,"a")); } EqualBean a1 = equalBeans.get(0); EqualBean a2 = equalBeans.get(1); System.out.println("a1.equals(a2):"+a1.equals(a2)); System.out.println("(a1 == a2):"+(a1 == a2)); System.out.println("equalBeans.contains(a1):"+equalBeans.contains(a1)); System.out.println("equalBeans.contains(new EqualBean(1,/"a/"))"+equalBeans.contains(new EqualBean(1,"a"))); System.out.println("a1.hashCode():"+a1.hashCode()); System.out.println("a2.hashCode():"+a2.hashCode()); System.out.println("new.hasCode():"+new EqualBean(1,"a").hashCode()); Map<EqualBean, Object> map = new HashMap<EqualBean, Object>(); EqualBean m = new EqualBean(1, "a"); map.put(m, "Hello"); System.out.println("Hello".equals(map.get(new EqualBean(1, "a")))); } }
输出结果是什么?
System.out.println("a1.equals(a2):"+a1.equals(a2)); //false,因为a1.equals(a2)调用的是父类Object.equals()方法,两个引用为同一个对象时返回false System.out.println("(a1 == a2):"+(a1 == a2));//a1,a2为内存中不同的对象,因此返回false System.out.println("equalBeans.contains(a1):"+equalBeans.contains(a1));//true,因为a1是list中的一个对象 System.out.println("equalBeans.contains(new EqualBean(1,/"a/"))"+equalBeans.contains(new EqualBean(1,"a")));//false,看一下collection的javadoc,cotains方法调用的是对象的equals方法来判断对象是否在集合中,因为equals()返回false,所以结果为false System.out.println("a1.hashCode():"+a1.hashCode());//整数1 System.out.println("a2.hashCode():"+a2.hashCode());//整数2 System.out.println("new.hasCode():"+new EqualBean(1,"a").hashCode());//整数3 System.out.println("Hello".equals(map.get(new EqualBean(1, "a"))));//false,hashMap是通过hashCode来进行散列存值和取值的,存的时候是一个hashCode(整数1),而取的时候是另一个hashCode(整数3),因此得到的结果为false
如果我们想让两个对象只要id和name相同,就认为是一个对象,应该怎么办?
重写对象的equals方法
package com.crazycoder2010.equal; public class EqualBean { private int id; private String name; public EqualBean(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public boolean equals(Object obj) { if(!(obj instanceof EqualBean) || obj == null){ return false; } EqualBean bean = (EqualBean)obj; boolean idEquals = this.getId() == bean.getId(); if(this.name == null){ return idEquals && this.name == bean.getName(); }else{ return idEquals && this.name.equals(bean.getName()); } } }
再来看下输出结果是什么?
System.out.println("a1.equals(a2):"+a1.equals(a2)); //true,因为我们已经重写了bean的equals方法,因此只要连个Id和name相等,返回的就是true了 System.out.println("(a1 == a2):"+(a1 == a2));//a1,a2为内存中不同的对象,因此返回false System.out.println("equalBeans.contains(a1):"+equalBeans.contains(a1));//true,因为a1是list中的一个对象 System.out.println("equalBeans.contains(new EqualBean(1,/"a/"))"+equalBeans.contains(new EqualBean(1,"a")));//true,调用的是bean.equals()方法,因此返回true System.out.println("a1.hashCode():"+a1.hashCode());//整数1 System.out.println("a2.hashCode():"+a2.hashCode());//整数2 System.out.println("new.hasCode():"+new EqualBean(1,"a").hashCode());//整数3 System.out.println("Hello".equals(map.get(new EqualBean(1, "a"))));//false
我们看到,重写equals方法貌似解决了我们的问题了,但是hashMap的返回结果依旧不是我们期望的,怎么办呢,其实很简单,Object里有个hashCode方法,只要重写下就可以了