Java技能 —— 关于Object的 equals方法以及 Comparable<T>接口的运用
1. 业务场景
在我们日常开发各种业务场景中,经常会判断字段之间的对等,比如会用到这些方法StringUtils.isNotBank(XXX) , "XXX".equals("XXX")。
如果是两个对象之间,要作为对比,直接使用默认的equals方法就会出现问题,例如 Student A = studentDao.selectById(12138),
Student B = studentDao.selectById(12138),A.equals(B) ——> false。实际上,在我们业务处理上,这两个对象应该属于同一个人,也就是希望返回true。
另外有一个场景,List<Student> list ,希望list能简便获取到顺序排序的列表,如果用for循环则过于麻烦,结合上述说明,做出技能解析。
2. 编写示例代码
import java.io.Serializable;
import java.util.Date;
import java.util.List;
@Data
public class CrmMenuVo implements Serializable, Comparable<CrmMenuVo>{
/** 主键ID. */
private Long id;
/** 菜单ID. */
private String menuId;
/** 菜单编码. */
private String menuCode;
/** 菜单类型: 1=菜单,2=权限. */
private Integer menuType;
/** 排序. */
private Integer seq;
/** 接口路径. */
private String menuPath;
/** 应用ID. */
private String appId;
/** 父菜单ID. */
private String parentMenuId;
/** 描述. */
private String menuDesc;
/** 状态 0失效 1生效. */
private Integer status;
/** 创建时间. */
private Date createTime;
/** 创建人ID. */
private String createUserId;
/** 创建人名称. */
private String createName;
/** 更新时间. */
private Date updateTime;
/** 更新人ID. */
private String updateUserId;
/** 更新用户名称. */
private String updateName;
private String menuName;
private Integer menuDepth;
private String menuIcon;
/** 以下扩展字段 **/
private List<CrmMenuVo> children;
/**
* 勾中状态 : 0未勾 ,1勾中
*/
private int choose;
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
CrmMenuVo menuVo = (CrmMenuVo) o;
if (!id.equals(menuVo.id)) {
return false;
} else {
return true;
}
}
//实现对比接口
@Override
public int compareTo(CrmMenuVo crmMenuVo) {
if(Integer.parseInt(this.getMenuId()) > Integer.parseInt(crmMenuVo.getMenuId())){
return 1;
}
if(this.getMenuId().equals(crmMenuVo.getMenuId())){
return 0;
}
return -1;
}
}
3. 测试用例与结果分析
A. 重写equals方法,两个对象的主键ID相等,业务上认为两个对象是一样。
public class Test {
public static void main(String[] args) {
CrmMenuVo A = new CrmMenuVo();
A.setId(1L);
A.setMenuName("我是A");
CrmMenuVo B = new CrmMenuVo();
B.setId(1L);
B.setMenuName("我是A");
System.out.println("A 与 B 的结果:" + A.equals(B));
}
}
结果如下:

经过测试符合期望,重写该方法之后,list.contains(XXX)也是同样有效果的。如下图

A. 实现 Comparable<T>接口,更方便的获取List<Object>顺序列表
public class Test {
public static void main(String[] args) {
CrmMenuVo A = new CrmMenuVo();
A.setId(1L);
A.setMenuId("10");
A.setMenuName("我是A");
CrmMenuVo B = new CrmMenuVo();
B.setId(3L);
B.setMenuId("30");
B.setMenuName("我是A");
CrmMenuVo C = new CrmMenuVo();
C.setId(2L);
C.setMenuId("20");
C.setMenuName("我是C");
List<CrmMenuVo> list = new ArrayList<CrmMenuVo>();
list.add(A);
list.add(B);
list.add(C);
System.out.println("list (未排序):" + list.toString());
//排序 调整
Collections.sort(list);
System.out.println("list (排完序):" + list.toString());
}
}

经过测试验证符合预期结果,而且比较简便的用一句代码将list进行排序。(以上是2019-07-30的Java基础技能,保持每周能有4篇随笔)

浙公网安备 33010602011771号