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篇随笔)