重写equals()与hashcode()方法,及comparable接口的实现

感谢:
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);
        }   
    }
}

运行结果:
以上代码运行结果

Thanks!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值