1、什么是哈希码(HashCode)

在Java中,哈希码代表对象的特征。例如对象

Java代码
  1. String str1 = “aa”, str1.hashCode= 3104
  2. String str2 = “bb”, str1.hashCode= 3106
  3. String str3 = “aa”, str1.hashCode= 3104

根据HashCode由此可得出str1!=str2,str1==str3

哈希码产生的依据:
哈希码并不是完全唯一的,它是一种算法,让同一个类的对象按照自己不同的特征尽量的有不同的哈希码,但不表示不同的对象哈希码完全不同。也有相同的情况,看程序员如何写哈希码的算法。

下面给出几个常用的哈希码的算法。

1:Object类的hashCode.返回对象的内存地址经过处理后的结构,由于每个对象的内存地址都不一样,所以哈希码也不一样。

2:String类的hashCode.根据String类包含的字符串的内容,根据一种特殊算法返回哈希码,只要字符串内容相同,返回的哈希码也相同。

3:Integer类,返回的哈希码就是Integer对象里所包含的那个整数的数值,例如Integer i1=new
Integer(100),i1.hashCode的值就是100
。由此可见,2个一样大小的Integer对象,返回的哈希码也一样。

2、equals方法在hibernate中的应用。

equals方法是默认的判断2个对象是否相等的方法,在Object类里有实现,判断的是2个对象的内存地址。在hibernate中,不允许存在同类对象中有2个一样的实例。hibernate通过equals方法做判断。如:

Java代码
  1. User u1 = new User(“张三”);
  2. User u2 = new User(“李四”);
  3. User u3 = new User(“张三”);

按照项目需求,用户只要名字相同,就表示同一个用户,所以我们认为,u1和u3是同一个人,同一个对象。但是因为u1,u2,u3三者的内存地址都各不相同,所以hibernate会认为这是3个不同的对象。这与我们假设的出了矛盾。

因此,我们将覆盖User的equals方法。

Java代码
  1. public class User{
  2. private String userName;
  3. ….//get ,set方法省
  4. //覆盖Object里的equals方法
  5. public boolean equals(Object arg0){
  6. if(!(arg0 instanceof User)){
  7. return false;
  8. }
  9. User user = (User)arg0;
  10. //如果名字相同,则表示属于同一个对象。
  11. if(user.getName().equals(this.getName)){
  12. return true;
  13. }else{
  14. return false;
  15. }
  16. }

这样hibernate在插入数据的时候,如果传过来一个叫”张三”的用户,hibernate会先判断有没有叫“张三”的用户,如果没有,就允
许插入,如果有,就不允许插入。这样做可以保证数据的高度一致性,不同的项目有不同的需求,所以要根据自己的需求来覆盖equlas方法。

3、为什么不按主键来判断
因为主键是在插入数据进数据库之后才产生的,在一个对象还没有被持久化的时候,它是没有主键的,所以hibernate无法根据主键判断它是否有相同数据。

equlas和HashCode的关系。

在hibernate中,它认为2个对象只要equlas返回true,那么hashCode一定相等。

但是实际情况呢?

Java代码
  1. User u1 = new User(“张三”);
  2. User u2 = new User(“张三”);

由于我们重写了User的equlas方法,所以
u1.equlas(u2);返回true
但是,User并没有重写hashCode方法,它用的是Object类的hashCode方法,所以
u1.hashCode = 31050006
u2.hashCode = 31587890
两者的hashCode并不相等。违背了hibernate的原则

由此hibernate会产生错误判断,又以为它们不是同一个对象,因此我们还得重写User
的hashCode方法。如何重写hashCode方法呢?

4、HashCode的重写。

如第2节所讲,哈希码要完成这么一件事,首先要保证如果equlas出来的结果相等,那么hashCode也相等。
像上面的u1和u2,由于名字都是“张三”,所以应该返回相同的hashCode。所以我们可以想一个办法。让User的哈希码返回User里面name字段的哈希码,这样就保证,名字相同的人,不但equlas方法相同,而且hashCode相等。

那么User类就变成

Java代码
  1. public class User{
  2. private String userName;
  3. //覆盖Object里的equals方法
  4. public boolean equals(Object arg0){
  5. if(!(arg0 instanceof User)){
  6. return false;
  7. }
  8. User user = (User)arg0;
  9. //如果名字相同,则表示属于同一个对象。
  10. if(user.getName().equals(this.getName)){
  11. return true;
  12. }else{
  13. return false;
  14. }
  15. }

//覆盖Object里的hashCode方法

Java代码
  1. public int hashCode(){
  2. return name.hashCode();//返回名字的哈希码。
  3. }

这样可以保证hibernate根据我们自己的需求来判断重复对象

JAVA中的各种 哈希码(HashCode) 与 equals方法在HIBERNATE的实际应用[转载]的更多相关文章

  1. K:java中的hashCode和equals方法

      hashCode和equals方法是Object类的相关方法,而所有的类都是直接或间接的继承于Object类而存在的,为此,所有的类中都存在着hashCode和equals.通过翻看Object类 ...

  2. 什么是哈希码(HashCode)

    什么是哈希码(HashCode) 在Java中,哈希码代表对象的特征. 例如对象 String str1 = “aa”, str1.hashCode= 3104 String str2 = “bb”, ...

  3. 关于java中的hashcode和equals方法原理

    关于java中的hashcode和equals方法原理 1.介绍 java编程思想和很多资料都会对自定义javabean要求必须重写hashcode和equals方法,但并没有清晰给出为何重写此两个方 ...

  4. Java中Set的contains()方法——hashCode与equals方法的约定及重写原则

    转自:http://blog.csdn.net/renfufei/article/details/14163329 翻译人员: 铁锚 翻译时间: 2013年11月5日 原文链接: Java hashC ...

  5. Java 中正确使用 hashCode 和 equals 方法

    在这篇文章中,我将告诉大家我对hashCode和equals方法的理解.我将讨论他们的默认实现,以及如何正确的重写他们.我也将使用Apache Commons提供的工具包做一个实现. 目录: hash ...

  6. 原码、补码,反码以及JAVA中数值采用哪种码表示

    原码.补码,反码以及JAVA中数值采用哪种码表示 1.原码定义(摘自百度百科):一种计算机中对数字的二进制定点表示方法,原码表示法在数值前面增加了一位符号位(即最高位为符号位):正数该位为0,负数该位 ...

  7. (转)Java 中正确使用 hashCode 和 equals 方法

    背景:最近在编写持久化对象时候遇到重写equals和hashCode方法的情况,对这两个方法的重写做一个总结. 链接:https://www.oschina.net/question/82993_75 ...

  8. Java中正确使用hashCode和equals方法

    在这篇文章中,我将告诉大家我对hashCode和equals方法的理解.我将讨论他们的默认实现,以及如何正确的重写他们.我也将使用Apache Commons提供的工具包做一个实现. 目录: hash ...

  9. Java学习从菜鸟变大鸟之一 hashCode()和equals()的本质区别和联系

    在学习java,根据视频做实例的过程中,对equals和hashcode两个方法理解稍微深刻一点,主要是它们两个很容易混淆,容易出错,自己又通过网上的资料学习,和大家分享 equals()方法 equ ...

随机推荐

  1. python(4) - 装饰器2

    接下来修改一下上一篇的login,将用户名传递给验证函数. def login(func): #接收一个函数作为参数 def inner(name): print("用户验证通过....&q ...

  2. wpf 父控件透明子控件不透明

    在wpf开发中遇到子控件会继承父类控件属性的问题, 例如: <StackPanel Orientation="Horizontal" Grid.Row="1&quo ...

  3. JavaScript中常用函数(入门级)(持续更新)

    本文中枫竹梦介绍一些JavaScript中入门级的常用函数,对于已经过了入门的童鞋可选择略过,都是一些非常实用的函数.如果发现什么问题,欢迎讨论. 问题列表 Q1: 设计一个函数repeatIt(st ...

  4. javaweb学习总结十三(dom4j方式对XML文档进行解析以及Xpath的使用)

    一:dom4j方式介绍 对于xml的解析总共有三种 1:jaxp方式,是sun公司开发的,分为sax方式和dom方式 2:jdom方式,后来其中部分人员参与开发dom4j 3:dom4j方式,是现在企 ...

  5. oracle 10g升级到11g

    Linux 上Oracle RAC 10g 升级到 Oracle RAC 11g 了解如何在 Oracle Enterprise Linux 5 上逐步将 Oracle RAC 10g 第 2 版升级 ...

  6. js验证 button 提交

    <form class="form-horizontal" role="form" action="member_add" metho ...

  7. Anroid之Intent的使用

    inten常见动作:MAIN_ACTION(主视图). VIEW_ACTION(查看). EDIT_ACTION(修改). PICK_ACTION(选择) .GET_CONTENT_ACTION(获取 ...

  8. 常用经典SQL语句大全(技巧)

    三.技巧 1.1=1,1=2的使用,在SQL语句组合时用的较多 “where 1=1” 是表示选择全部    “where 1=2”全部不选, 如: if @strWhere !='' begin s ...

  9. ios Swift 国外资源

    Swift国外资源汇总(No.1) 此类分享贴暂定每2天更新一次,主要目的是让大家能跟国外开发者们同步,共享知识和共同提高. 对于一些非常有价值的文章,大家有兴趣可以自行翻译(回贴跟我说一声,避免重复 ...

  10. jquery获取文档高度和窗口高度的例子

    jquery获取文档高度和窗口高度,$(document).height().$(window).height() $(document).height():整个网页的文档高度 $(window).h ...