正确重写hashCode方法

例一:

import java.util.List;
 
public class Dish {
 
    private String dishCode;
    
    private boolean weighing;
 
    private String categoryCode;
 
    private boolean currentPrice;
 
    private boolean discountable;
 
    private boolean stopSell;
 
    private boolean soldOut;
 
    private boolean deal = false;
 
    private List dealGroupList;
 
    public String getDishCode() {
        return dishCode;
    }
 
    public void setDishCode(String dishCode) {
        this.dishCode = dishCode;
    }
 
    public boolean isWeighing() {
        return weighing;
    }
 
    public void setWeighing(boolean weighing) {
        this.weighing = weighing;
    }
 
    public String getCategoryCode() {
        return categoryCode;
    }
 
    public void setCategoryCode(String categoryCode) {
        this.categoryCode = categoryCode;
    }
 
    public boolean isCurrentPrice() {
        return currentPrice;
    }
 
    public void setCurrentPrice(boolean currentPrice) {
        this.currentPrice = currentPrice;
    }
 
    public boolean isDiscountable() {
        return discountable;
    }
 
    public void setDiscountable(boolean discountable) {
        this.discountable = discountable;
    }
 
    public boolean isStopSell() {
        return stopSell;
    }
 
    public void setStopSell(boolean stopSell) {
        this.stopSell = stopSell;
    }
 
    public boolean isSoldOut() {
        return soldOut;
    }
 
    public void setSoldOut(boolean soldOut) {
        this.soldOut = soldOut;
    }
 
    public boolean isDeal() {
        return deal;
    }
 
    public void setDeal(boolean deal) {
        this.deal = deal;
    }
 
    public List getDealGroupList() {
        return dealGroupList;
    }
 
    public void setDealGroupList(List dealGroupList) {
        this.dealGroupList = dealGroupList;
    }
 
 
    @Override
    public int hashCode() {
        int result = dishCode != null ? dishCode.hashCode() : 0;
        result = 31 * result + (soldOut ? 1 : 0);
        result = 31 * result + (stopSell ? 1 : 0);
        result = 31 * result + (currentPrice ? 1 : 0);
        result = 31 * result + (weighing ? 1 : 0);
        result = 31 * result + (categoryCode != null ? categoryCode.hashCode() : 0);
        result = 31 * result + (dealGroupList != null ? dealGroupList.hashCode() : 0);
        return result;
    }
 
}

其重写了hashcode方法,我们知道如果重写hashcode方法是用到了对象类型,那么该对象类型也必须要重写hashcode方法,否则每次得到的hashcode值不一定一致,那么重写hashcode方法的意义就不大了;

我们发现这里面用到了dealGroupList这个对象,所有我们必须要重写这个对象里面元素的hashcode方法,即DealGroup对象;


DealGroup类结构:

import java.math.BigDecimal;
 
public class DealGroup {
 
    /**
     * 是否可选 (必填) 枚举类型
     */
    private OptionalTypeEnum optionalType;
 
    private boolean repeatable;
 
    private BigDecimal minChooseNum;
 
    private BigDecimal maxChooseNum;
 
    private boolean hasExtraPrice = false;
 
    public OptionalTypeEnum getOptionalType() {
        return optionalType;
    }
 
    public void setOptionalType(OptionalTypeEnum optionalType) {
        this.optionalType = optionalType;
    }
 
    public boolean isRepeatable() {
        return repeatable;
    }
 
    public void setRepeatable(boolean repeatable) {
        this.repeatable = repeatable;
    }
 
    public BigDecimal getMinChooseNum() {
        return minChooseNum;
    }
 
    public void setMinChooseNum(BigDecimal minChooseNum) {
        this.minChooseNum = minChooseNum;
    }
 
    public BigDecimal getMaxChooseNum() {
        return maxChooseNum;
    }
 
    public void setMaxChooseNum(BigDecimal maxChooseNum) {
        this.maxChooseNum = maxChooseNum;
    }
 
    public boolean isHasExtraPrice() {
        return hasExtraPrice;
    }
 
    public void setHasExtraPrice(boolean hasExtraPrice) {
        this.hasExtraPrice = hasExtraPrice;
    }
 
    @Override
    public int hashCode() {
        int result = optionalType != null ? optionalType.hashCode() : 0;
        result = 31 * result + (minChooseNum != null ? minChooseNum.hashCode() : 0);
        result = 31 * result + (maxChooseNum != null ? maxChooseNum.hashCode() : 0);
        return result;
    }
}

 

到这里,对象写完了,开始描述问题。

计算hashCode的注意事项:

1、不能包含equals方法中没有的字段,否则会导致相等的对象可能会有不同的哈希值。

    (即对类中每一个重要字段,也就是影响对象的值的字段,也就是equals方法里有比较的字段,进行操作)

2、String对象和Bigdecimal对象已经重写了hashcode方法,这些类型的值可以直接用于重写hashcode方法;

3、result = 31 *result + (dishCode !=null ?dishCode.hashCode() : 0);,这里面为啥用个31来计算,而且很多人都是这么写的,这是因为31是个神奇的数字,任何数n*31都可以被jvm优化为(n<<5)-n,移位和减法的操作效率比乘法的操作效率高很多!

4、Google首席Java架构师Joshua Bloch在他的著作《Effective Java》中提出了一种简单通用的hashCode算法:

     ①初始化一个整形变量,为此变量赋予一个非零的常数值,比如int result = 17;

     ②如果是对象应用(例如有String类型的字段),如果equals方法中采取递归调用的比较方式,那么hashCode中同样采取递归调用hashCode的方式。否则需要为这个域计算一个范式,比如当这个域的值为null的时候(即 String a = null 时),那么hashCode值为0

 

例二:

正确重写hashCode方法_第1张图片

由于areaCode和localNumber都是用来区分TantanitReaderPhone的重要字段,所以根据这两个字段来计算哈希值。这两个字段都是String类型,直接调用String自带的hashCode方法(areaCode和localNumber假定都不为null)。

 

--------------------- 
原文:https://blog.csdn.net/zhengchao1991/article/details/78916471 

你可能感兴趣的:(JAVA)