转自:http://hi.baidu.com/1900spy/blog/item/29e822dae79b2fddb6fd48e7.html
1、什么是哈希码(HashCode)
在Java中,哈希码代表对象的特征。例如对象
String str1 = “aa”, str1.hashCode= 3104
String str2 = “bb”, str1.hashCode= 3106
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方法做判断。如:
User u1 = new User(“张三”);
User u2 = new User(“李四”);
User u3 = new User(“张三”);
按照项目需求,用户只要名字相同,就表示同一个用户,所以我们认为,u1和u3是同一个人,同一个对象。但是因为u1,u2,u3三者的内存地址都各不相同,所以hibernate会认为这是3个不同的对象。这与我们假设的出了矛盾。
因此,我们将覆盖User的equals方法。
public class User{
private String userName;
….//get ,set方法省
//覆盖Object里的equals方法
public boolean equals(Object arg0){
if(!(arg0 instanceof User)){
return false;
}
User user = (User)arg0;
//如果名字相同,则表示属于同一个对象。
if(user.getName().equals(this.getName)){
return true;
}else{
return false;
}
}
这样hibernate在插入数据的时候,如果传过来一个叫”张三”的用户,hibernate会先判断有没有叫“张三”的用户,如果没有,就允许插入,如果有,就不允许插入。这样做可以保证数据的高度一致性,不同的项目有不同的需求,所以要根据自己的需求来覆盖equlas方法。
3、为什么不按主键来判断
因为主键是在插入数据进数据库之后才产生的,在一个对象还没有被持久化的时候,它是没有主键的,所以hibernate无法根据主键判断它是否有相同数据。
equlas和HashCode的关系。
在hibernate中,它认为2个对象只要equlas返回true,那么hashCode一定相等。
但是实际情况呢?
User u1 = new User(“张三”);
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类就变成
public class User{
private String userName;
//覆盖Object里的equals方法
public boolean equals(Object arg0){
if(!(arg0 instanceof User)){
return false;
}
User user = (User)arg0;
//如果名字相同,则表示属于同一个对象。
if(user.getName().equals(this.getName)){
return true;
}else{
return false;
}
}
//覆盖Object里的hashCode方法
public int hashCode(){
return name.hashCode();//返回名字的哈希码。
}
}
这样可以保证hibernate根据我们自己的需求来判断重复对象
分享到:
相关推荐
`UserType`提供了对Java对象和数据库列之间转换的一系列方法,包括获取SQL类型的数组(`sqlTypes()`)、返回对象的Java类(`returnedClass()`)、比较两个对象的持久化相等性(`equals()`)、计算对象的哈希值(`...
在Java编程语言中,Hibernate是一个流行的ORM(对象关系映射)框架,它允许开发者将数据库操作转换为面向对象的方式,...在实际应用中,根据具体需求选择合适的主键策略,将有助于优化数据库设计和提高数据访问性能。
hashCode 方法用于返回对象的哈希码,equals 方法用于比较两个对象是否相等。 50. Java 接口继承 * Java 中什么是接口继承?接口继承是一种机制,用于继承多个接口。 51. Java 组合和聚合关系 * Java 中什么是...
以下是一些Java面试中的重要知识点,包括JDK和JRE的区别、`==`与`equals()`的差异以及`hashCode()`和`equals()`的关系。 **JDK与JRE的区别** JDK(Java Development Kit)是Java开发工具包,它包含了JRE(Java ...
- **equals()和hashCode()**:解释了如何正确实现这些方法以确保对象的等价性和哈希表操作的正确性。 - **动态模型**:介绍了如何使用动态模型来处理不固定结构的数据。 - **Tuplizers**:提供了关于元组片段映射...
在Java中,hashCode()和equals()是Object类的两个重要方法。hashCode()返回对象的哈希码,用于确定对象在哈希表中的索引位置。equals()方法用来比较两个对象的内容是否相等。在使用HashMap等集合时,这两个方法的...
由于联合主键类需要被用作哈希表中的键,因此必须重写 `hashCode()` 和 `equals()` 方法,确保当两个 `SCMapping` 实例具有相同的学号和课程号时,它们被视为相等。 3. **编写映射文件**: 使用 Hibernate 映射...
Hibernate是一个流行的ORM(对象关系映射)框架,简化了Java应用与数据库之间的交互。它允许开发者使用面向对象的方式来操作数据库,通过XML或注解配置来映射对象到数据库表。 10. **JVM内存模型**: JVM内存分为...
在Java面试中,深入理解各种概念和技术是至关重要的。这里我们详细探讨一下标题和描述中提到的一些关键知识点。 1. **JDK与JRE的区别**: - JDK(Java Development Kit)是Java开发工具包,它包括JRE(Java ...
- **equals()与hashCode()方法**:为了正确的对象比较和哈希计算,需要正确实现这两个方法。 - **动态模型**:使用动态代理技术来支持动态创建的实体类。 - **元组片段映射**:介绍了一种特殊的映射机制,用于更...
- `hashCode`通常与`equals`一起使用,当两个对象`equals`相等时,它们的`hashCode`也应相等,以便于对象在哈希表(如HashSet或HashMap)中的正确存储和查找。然而,如果仅`==`相等,`hashCode`不一定相等,这取决...
- **equals方法**:在Object类中,equals默认实现也是基于==运算符来比较引用的,即比较两个引用是否指向同一个对象。但String、Integer等类重写了equals方法,使得它们比较的是值而非引用。因此,对于String和...
`User2`类同样实现了`Serializable`接口,并提供了`equals()`和`hashCode()`方法,虽然在示例中这些方法尚未完成,但在实际应用中,为了确保对象的正确比较和哈希桶存储,这两个方法需要根据主键属性来实现。...
在这个例子中,尽管 `str1` 和 `str2` 的 `hashCode()` 可能相同,但 `str1.equals(str2)` 返回 `false`,表明它们的值不同。 #### 容器 - Java 中的容器主要分为集合(Collection)和映射(Map)两大类。 - **...
在J2EE企业级项目开发中,经常遇到复杂的数据库操作,特别是当数据量达到百万级别时,高效的查询和数据管理...在实际应用中,根据项目的具体需求和所使用的框架特性,合理地运用这些技术能显著提高开发效率和系统性能。
- 确保对象的正确比较和哈希码一致性。 **5.4 动态模型** - **动态模型支持** - 使用反射机制动态创建持久化对象。 #### 六、基本 ORM 映射 **6.1 映射声明** - **文档类型** - 映射文件的根元素必须包含...
- **equals() 和 hashCode()**:实现这些方法以确保对象的正确比较和哈希表操作。 - **动态模型**:使用动态模式处理不固定列数的表。 - **元组片断映射**:通过自定义实现提高性能和灵活性。 **对象/关系数据库...
Java作为一门广泛使用的编程语言,其面试题涵盖了众多的知识点,包括基础概念、容器、多线程、反射、对象拷贝、Web开发、异常处理、网络编程、设计模式以及各种框架如Spring、Hibernate、Mybatis等。以下是对部分...
小辣椒插件Lombok是一款广泛应用于Java开发领域的工具,它极大地简化了代码的编写,特别是对于getter、setter、equals、hashCode、toString等繁琐的样板代码。Lombok通过注解处理器在编译时自动插入这些方法,使得源...