感谢:
http://blog.sina.com.cn/s/blog_5da93c8f0101djjr.html
http://www.cnblogs.com/gnuhpc/archive/2012/12/17/2822251.html
equals()与hashcode()
引例
/*
*Employee类,setget方法
*没有重写equals()与hashcode()方法
*/
public class Employee {
private Integer id;
private String firstname;
private String lastName;
private String department;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
}
测试
public class TestEmployee {
public static void main(String[] args) {
Employee emp1=new Employee();
Employee emp2=new Employee();
emp1.setId(100);
emp2.setId(100);
System.out.println(emp1.equals(emp2));
}
}
输出结果: false
但是,事实上上面两个对象代表的是通过一个employee。真正的商业逻辑希望我们返回true。
为了达到这个目的,我们需要重写equals方法。
/*
* 重写equals必须注意:
* 1 自反性:对于任意的引用值x,x.equals(x)一定为true
* 2 对称性:对于任意的引用值x 和 y,当x.equals(y)返回true, *y.equals(x)也一定返回true
* 3 传递性:对于任意的引用值x、y和z,如果x.equals(y)返回true,并*且y.equals(z)也返回true,那么x.equals(z)也一定返回 true
* 4 一致性:对于任意的引用值x 和 y,如果用于equals比较的对象信息没有被修改,
* 多次调用x.equals(y)要么一致地返回true,要么一致地返回*false
* 5 非空性:对于任意的非空引用值x,x.equals(null)一定返回false
*
*
*/
public boolean equals(Object o) {
if(o == null)
{
return false;
}
if (o == this)
{
return true;
}
if (getClass() != o.getClass())
{
return false;
}
Employee e = (Employee) o;
return (this.getId() == e.getId());
}
**
输出结果: true
请注意:
我们再做测试:
public class TestEmployee {
public static void main(String[] args) {
Employee emp1 = new Employee();
Employee emp2 = new Employee();
emp1.setId(100);
emp2.setId(100);
System.out.println(emp1.equals(emp2));
//true
Set employees = new HashSet();
employees.add(emp1);
employees.add(emp2);
// Prints two objects
System.out.println(employees);
}
}
**
打印结果: true
[com.equal.Employee@d73c7a, com.equal.Employee@79ed7f]
说明:上面的程序第一个是true毫无疑问,第二个输出的结果明显是两个。如果两个employee对象equals返回true,Set中应该只存储一个对象才对,问题在哪里呢?
我们忘掉了第二个重要的方法hashCode()
@Override
public int hashCode() {
final int PRIME = 31;
int result = 1;
result = PRIME * result + getId();
return result;
}
**再次运行上面的测试代码,结果为:
true
[com.equal.Employee@83]**
OK!!
实现comparable接口
1.什么是Comparable接口
此接口强行对实现它的每个类的对象进行整体排序。此排序被称为该类的自然排序 ,类的 compareTo 方法被称为它的自然比较方法 。实现此接口的对象列表(和数组)可以通过 Collections.sort (和 Arrays.sort )进行自动排序。实现此接口的对象可以用作有序映射表中的键或有序集合中的元素,无需指定比较器。
2.实现什么方法
**int compareTo(T o)
比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。**
示例:
//实现Comparable 接口
public class Employee implements Comparable {
private Integer id;
private String firstname;
private String lastName;
private String department;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
//实现comparable接口的compareTo方法
@Override
public int compareTo(Object o) {
if (o instanceof Employee) {
Employee employee = (Employee) o;
if (this.id > employee.id) {
return 1;
}
if (this.id < employee.id) {
return -1;
}
return 1;
} else {
System.out.println("compare type error");
return -2;
}
}
@Override
public String toString() {
return "Employee [id=" + id + ", firstname=" + firstname
+ ", lastName=" + lastName + ", department=" + department + "]";
}
}
下面进行测试,代码如下:
public class TestEmpCompare {
public static List<Employee> employees = new ArrayList<Employee>();
public static Employee emp;
//初始化一些Employee对象,放入list中
static {
for (int i = 0; i < 10; i++) {
emp = new Employee();
emp.setId((int) (Math.random() * 10000));
emp.setFirstname("三子" + i);
emp.setLastName("张三" + i);
emp.setDepartment("001" + i);
employees.add(emp);
}
}
@SuppressWarnings("unchecked")
public static void main(String[] args) {
for (Employee emp:employees) {
System.out.println(emp);
}
System.out.println("----------------华丽的分隔线---------------");
//实现排序方法sort(list)
Collections.sort(employees);
for (Employee emp:employees) {
System.out.println(emp);
}
}
}
运行结果: