转自: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根据我们自己的需求来判断重复对象
分享到:
相关推荐
java中的哈希算法和hashcode深入讲解1
hashCode():计算出对象实例的哈希码,并返回哈希码,又称为散列函数。根类Object的hashCode()方法的计算依赖于对象实例的D(内存地址),故每个Object对象的hashCode都是唯一的;当然,当对象所对应的类重写了...
文章目录1、hashCode与equals两者之间的关系2、== 和equals的区别`3、为什么要重写equals()方法?4、重写equals()方法5、为什么要重写hashCode()方法?6、什么时候需要重写hashCode()方法?7、重写hashCode()方法: ...
很多密码都是哈希后保存的,由于哈希码由不可逆的函数生成,我们没有办法直接解密。如果要快速破解这类码值,综合使用多种资源……
但是为什么JavaDoc明确的告诉我们, hashCode()...HashMap底层用于存储数据的结构其实是散列表(也叫哈希表),散列表是通过哈希函数将元素映射到数组指定下标位置, 在Java中,这个哈希函数其实就是hashCode()方法。
在Java应用程序执行期间,在同一对象上多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是对象上equals比较中所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需...
Java中的哈希表
java源码:哈希计算工具 java-hash.7z
哈希表 哈希表.java Java对哈希表的操作
哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率。在Java的Object类中有一个方法: public native int hashCode();...在Java中也一样,hashCode方法的主要作用是为了配合基于
Java哈希表性能优化
哈希码破解利器说明
Java中入HashMap等一些键值对应的结构,基本上都可以用hashCode()来查找值,接下来我们就来详解Java中用于查找对象哈希码值的hashCode()函数:
Java数据结构 线性表,链表,哈希表是常用的数据结构,在进行Java开发时,JDK已经为我们提供了一系列相应的类来实现基本的数据结构
哈希表java代码
基于java的开发源码-哈希计算工具 Java-hash.zip 基于java的开发源码-哈希计算工具 Java-hash.zip 基于java的开发源码-哈希计算工具 Java-hash.zip 基于java的开发源码-哈希计算工具 Java-hash.zip 基于java的开发...
Object类的hashCode的用法 马克-to-win java视频哈希码
在实际应用中,我们应该根据具体的需求和安全要求选择合适的哈希算法。 通过本文,您应该对Java中MessageDigest的digest()方法有了更深入的了解。希望这篇文章能够帮助您更好地理解和应用哈希函数的概念和方法。
在lawa中,每个对象都可以调用自己的hashCode)方法得到自己的哈希值(hashCode),相当于对象的指纹信息,通常来说世界上没有完全相同的两个指纹,但是在Java中做不到这么绝对,但是我们仍然可以利用hashCode来做一些...
哈希表 哈希表_使用Java开发的哈希表_HashTable