对象的相等与比较

                                                         对象的相等与比较
     近一年多来,拜托轻量级容器的流行,POJO的使用率也随之上升。POJO的功能很简单,主要是用来在各模块之间传递数据。比如,有这么一个User类:
 public class User
 {
   private int id;
   private String name;
   public void setId(int id)
   {
    this.id = id;
 }
 public int getId()
 {
  return this.id;
 }
 public void setName(String name)
 {
  this.name = name;
 }
 public String getName()
 {
  return this.name;
 }
 ……
 }
      这个类的功能很简单,实现了POJO的基本功能,几乎所有的POJO都是这么一个模样。但是,仅仅这样的功能,我们在使用中经常会感到有些不方便。比如,我们可能会在业务逻辑中比较两个User对象是否为同一个User。就会有如下的代码:
 if(user1.getId()==user2.getId())
 {
   ……
 }
      对于这样的代码,看上去就感觉怪怪的,为什么?我们的目的是要两个User对象是否为同一个User,但判断语句却是在判断两个User对象的id是否相等,看到这个语句不能给人一种是在判断两个User是否为同一个User的感觉。如果改为下面的代码,是否给人感觉好一些呢?
 If(user1.equals(user2))
 {
   ……
 }
      这样一看代码就知道是在比较两个User对象是否为同一个User,代码的可读性就强多了。
      这还不是需要改造代码的全部原因,如果在多个业务逻辑类里经常出现这样的判断,那么这就造成了一定的代码重复,是我们所忌讳的。
 其实,equals方法继承自Object类,只要我们在POJO类里重写该方法就可以使用了。比如,在User类里改写如下:
 public class User
 {
   ……
   public boolean equals(Object o)
   {
    //如果o为空,则返回false
    if(o==null) return false;
    //如果是同一个对象,则返回true
    else if(o==this) return true;
    //如果是User类的对象,且id相等,则返回true
    else if(o instanceof User && ((User)o).getId()==this.id) return true;
    else return false;
 }
 }
      有了这个对象相等的方法,我们就可以在业务逻辑类中随时使用了,而不用使用取出id的有点dirty的代码了。
      更多的时候,我们也会有这样的判断语句:
 if(user1.getId==userId)
 {
   ……
 }
      比如,我们在删除user的时候,要是不是删除了本人。这一个判断也不妨放在equals方法里头,我们在User类里重载equals方法,如下:
 public boolean equals(int userId)
 {
   return this.id == userId;
 }
      呵呵,我们就可以这样判断:
 if(user1.equals(userId))
 {
   ……
 }
      这样,代码的可读性也要好一点。
      有了相等,就有不相等。如果不相等的话,就要比较大小。例如,对容器里的对象进行排序或查找,就需要比较大小了。
      Arrays类里涉及到对象比较的方法有两个:
 Sort(Object[] os,Comparator comparator)
 BinarySearch(Object[] os,Object o,Comparator comparator)
      然后,Collections类里也有类似的两个方法,其他的容器类里也应该有类似的方法。所有的这些方法都要涉及到有关对象的比较,具体就是实现Comparator接口。
      比如有这么一个Employee类:
 public class Employee
 {
   private long id;
   private String name;
   private int servedYears;
   public void setId(long id)
   {
    this.id = id;
 }
 public long getId()
 {
  return this.id;
 }
 public void setName(String name)
 {
  this.name = name;
 }
 public String getName()
 {
  return this.name;
 }
 public void setServedYears(int servedYears)
 {
  this.servedYears = servedYears;
 }
 public int getServedYears()
 {
  return this.servedYears;
}
……
 }
      我们需要按员工的工作年数来排序,比如员工存在一个数组里:Employee[] emps = ……,则我们的排序代码为:
 Arrays.sort(emps,new Comparator(){
   Public int compare(Object o1,Object o2)
   {
    int sy1 = ((Employee)o1).getServedYears();
    int sy2 = ((Employee)o2).getServedYears();
    if(sy1>sy2) return 1;
    else if(sy1<sy2) return –1;
    else return 0;
 }
 });
     示例代码1

      sort方法里的匿名内部类需要实现compare方法。该方法有两个参数o1和o2,我们先是分别取出o1和o2的工作年数,然后,如果按照o1的工作年数大于o2的工作年数则返回一个正数,小于则返回一个负数,等于返回零的话,如上面的示例代码1所示,则数组按员工的年作年数的顺序排序。
      否则,如果按照o1的工作年数小于o2的工作年数则返回一个正数,大于则返回一个负数,等于返回零的话,如上面的代码所示,则数组按员工的年作年数的倒序排序。如下面的代码所示:
 Arrays.sort(emps,new Comparator(){
   Public int compare(Object o1,Object o2)
   {
    int sy1 = ((Employee)o1).getServedYears();
    int sy2 = ((Employee)o2).getServedYears();
    if(sy1<sy2) return 1;
    else if(sy1>sy2) return –1;
    else return 0;
 }
 });
      明白了排序的原理以后,我们可以看到上面示例代码1的代码还可以简化,如下所示:
 Arrays.sort(emps,new Comparator(){
   Public int compare(Object o1,Object o2)
   {
    return ((Employee)o1).getServedYears()-((Employee)o2).getServedYears();
 }
 });
      在上面的代码里,返回的那个简单的算式结果其实就是示例代码1的那些代码的变形,也是o1的工作年数大于o2的工作年数则返回一个正数,小于则返回一个负数,等于则返回零。
      关于方法binarySearch里的比较器和方法sort的一样适用。需要注意的是,在使用binarySearch方法的时候,先要将数组或者其他容器里的对象先排序,然后才能使用该方法来搜索某个对象。
      好了,说到这里,该说的正题都已经说完了。就一句废话:对象的equals方法和比较器Comparator使用起来都蛮简单的,在实际的工作中,大家不妨用用看。
阅读更多
个人分类: Java基础
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭