在我们对自定义的对象进行定义equal方法比较时,我们会重写方法并设置比对规则,但是需要对hashCode()方法进行重写,否则会存在程序bug的隐患
只重写equal方法,不重写hashCode方法时,程序编译和运行都不会报错,但是这样是不符合java编码规范的
因为java规范认为:如果两个对象equals,Java运行时环境会认为他们的hashcode一定相等
如果不重写hashCode,会导致该类无法结合所有基于散列的集合一起正常运作,这样的集合包括HashMap、HashSet
package com.blue.user.model.entity;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Objects;
/**
* <p>
* 角色和菜单关联表
* </p>
*
* @author liulei, lei.liu
* @version 1.0
*/
@Data
@Accessors(chain = true)
public class RoleMenu implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private Long id;
/**
* 菜单id
*/
@TableField("menu_id")
private Long menuId;
/**
* 角色id
*/
@TableField("role_id")
private Long roleId;
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (object == null) {
return false;
}
if (object instanceof RoleMenu) {
RoleMenu roleMenu = (RoleMenu) object;
return Objects.equals(roleMenu.getRoleId(), roleId)
&& Objects.equals(roleMenu.getMenuId(), menuId);
}
return false;
}
@Override
public int hashCode() {
int result = 0;
result = 31 * result + Objects.hashCode(menuId);
result = 31 * result + Objects.hashCode(roleId);
return result;
}
@Override
public String toString() {
return JSON.toJSONString(this);
}
}
package com.blue.common.util;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Map;
/**
* 比对工具类
*
* @author liulei, [email protected]
* @version 1.0
*/
public class CompareUtil {
private static Logger logger = LoggerFactory.getLogger(LocalDateUtils.class);
/**
* 需要追加的记录
*/
public static final String APPEND = "append";
/**
* 需要保留的
*/
public static final String REMAIN = "remain";
/**
* 需要删除的
*/
public static final String REMOVE = "remove";
/**
* 比对两组对象集合,得出结果
*
* @param source 源数据
* @param target 目标数据
* @return 比对结果
*/
public static <T> Map<String, List<T>> compareObjectList(List<T> source, List<T> target) {
Map<String, List<T>> map = Maps.newHashMap();
List<T> targetCopy = Lists.newArrayList(target);
targetCopy.retainAll(source);
map.put(REMAIN, targetCopy);
source.removeAll(targetCopy);
map.put(APPEND, source);
target.removeAll(targetCopy);
map.put(REMOVE, target);
logger.info("compare result: {}", map);
return map;
}
}
为什么使用31做基础?
1.spring也用
2.整数类型的哈希算法,对质数取模哈希冲突大大减少
3.jvm可以对31进行计算优化,31 * i = (i << 5) - i(左边 312=62,右边 22^5-2=62) - 两边相等,JVM就可以高效的进行计算