工作紀實_08-java對象比較

在我們對自定義的對象進行定義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就可以高效的進行計算

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章