例一:

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;}@Overridepublic 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;}@Overridepublic 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

正确重写hashCode方法相关推荐

  1. 重写 equals 方法就一定要重写 hashCode 方法?其实有个前提

    作者 l 会点代码的大叔(CodeDaShu) 如果问到 == 和 equals 的区别,相信很多程序员同学都能脱口而出:一个是判断地址,一个是判断内容. 但是如果继续追问:"你重写过 eq ...

  2. java重写面试题_Java面试题:重写了equals方法,为什么还要重写hashCode方法?

    核心问题:重写了equals方法,为什么还要重写hashCode方法? 这不仅仅是一道面试题,而且是关系到我们的代码是否健壮和正确的问题.在前面两篇文章涉及到了equals方法的底层讲解:<说说 ...

  3. java重写hashcode_正确重写hashCode的办法

    ------------------------------------------ 正确重写hashCode的办法 [1]. hashCode重写成相同的值的缺点 将所有对象的hashCode都返回 ...

  4. JAVA中重写equals()方法的同时要重写hashcode()方法

    object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true:注意:当此方法 ...

  5. hashcode相等的两个对象一定相等吗_为什么重写 equals方法时一定要重写hashCode方法?...

    推荐阅读: 一线架构师总结SpringBoot,Cloud,Nginx与Docker,不信你搞不懂 47天洒热血复习,我终于"挤进"了字节跳动(附面经+学习笔记) 五年时间,从蘑菇 ...

  6. 为什么要重写hashcode()方法

    主要原因是默认从Object继承来的hashCode是基于对象的ID实现的. 如果你重写了equals,比如说是基于对象的内容实现的,而保留hashCode的实现不变,那么很可能某两个对象明明是&qu ...

  7. 重写equals方法时必须重写hashcode方法吗

    重写equals方法时必须重写hashcode 有规范: 1,当obj1.equals(obj2) 为 true 时,obj1.hashCode() == obj2.hashCode() 2,当obj ...

  8. why在重写equals时还必须重写hashcode方法

    首先我们先来看下String类的源码:可以发现String是重写了Object类的equals方法的,并且也重写了hashcode方法 public boolean equals(Object anO ...

  9. java equals重写原则_java中为何重写equals时必须重写hashCode方法详解

    前言 大家都知道,equals和hashcode是java.lang.Object类的两个重要的方法,在实际应用中常常需要重写这两个方法,但至于为什么重写这两个方法很多人都搞不明白. 在上一篇博文Ja ...

最新文章

  1. 自己动手写简单的web应用服务器(4)—利用socket实现文件的下载
  2. 浅谈千万级PV/IP规模高性能高并发网站架构
  3. addslashes() 函数和PHP stripslashes() 函数
  4. 如何获取真实的执行计划
  5. 《Python快速入门》6大数据类型详解
  6. Android测量图像中物体大小,android – 加载图像后测量ImageView
  7. Radware:应用交付向云端扩展
  8. asp网络编程:用ASP实现网页BBS
  9. Atitit .c#的未来新特性计划草案
  10. 基于JAVA大众点评管理系统计算机毕业设计源码+系统+lw文档+部署
  11. python电脑怎么运行_如何运行python文件
  12. mysql将毫秒转换为小时_将毫秒转换为天小时分钟
  13. dubbo服务暴露流程总结
  14. 从faces_glintasia的.rec数据集转换为jpg图片
  15. python读取txt文件并将其转换为Dataframe格式
  16. 哪个骨传导蓝牙耳机的好,推荐几款口碑高的骨传导耳机
  17. Cerberus恶意软件团队解散,10万美元拍卖源代码工程
  18. arcmin 弧分的转换
  19. 大数据上云存算分离演进思考与实践
  20. 4.导出UnityPackage(AssetDatabase.ExportPackage(assetPathName ,fileName ,ExportPackageOptions.Recurse )

热门文章

  1. task02 fashion-mnist分类实战
  2. UTC、GMT、CST
  3. NetSuite Transaction表中的通用与专用字段
  4. 课程设计-基于JSP+Servlet的员工考勤管理系统
  5. Java switch()括号内参数的类型要求
  6. GPT-4 开始内测32k输入长度的版本了!你收到邀请了吗?
  7. IT技术晋级之路-锁定任务栏
  8. 致敬五四精神 十大“新青年志愿者之星”出炉
  9. java支付接口开发
  10. python编程——绘制创意图(pecharts、turtle)