例一:
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<DealGroup> 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<DealGroup> getDealGroupList() {
return dealGroupList;
}
public void setDealGroupList(List<DealGroup> 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
例二:
由于areaCode和localNumber都是用来区分TantanitReaderPhone的重要字段,所以根据这两个字段来计算哈希值。这两个字段都是String类型,直接调用String自带的hashCode方法(areaCode和localNumber假定都不为null)。
---------------------
原文:https://blog.csdn.net/zhengchao1991/article/details/78916471