哈希码
哈希码是一种算法,它的目的是让同一个类的对象按照自己不同的特征尽量地有不同的哈希码,但是,不表示不同的对象哈希码完全不同。也可能有相同的情况。在Java中,哈希码代表对象的特征。
hashCode
在Java中,hashCode是jdk根据对象的地址或者字符串或者是数字算出来的int类型的数值。
常见的哈希码的算法有:
1:Object类的hashCode :返回对象的内存地址经过处理后的结构,由于每个对象的内存地址都不一样,所以哈希码也不一样。
2:String类的hashCode :根据String类包含的字符串的内容,根据一种特殊算法返回哈希码,只要字符串内容相同,返回的哈希码也相同。
3:Integer类 :返回的哈希码就是Integer对象里所包含的那个整数的数值,例如Integer i1=new Integer(100),i1.hashCode的值就是100 。
equal
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个不同的对象。这与我们假设的出了矛盾。 因此,我们将覆盖Object类中的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会先判断有没有叫“张三”的用户,如果没有,就允许插入,如果有,就不允许插入。这样做可以保证数据的高度一致性,不同的项目有不同的需求,所以要根据自己的需求来覆盖equals方法。
哈希学习
哈希学习的目的:
通过机器学习机制将数据映射成简洁的二进制串的形式,同时使得哈希码尽可能地保持原空间中的近邻关系,即保相似性。
比如下面的例子:
原始数据是三幅图像,其中后面这两幅相似度比较高,也就是说在原始空间中从语义层次的距离或者欧氏距离都比较近,映射为哈希码之后,距离也应该更近。
哈希学习的分类:
- 第一种的代表是局部敏感哈希,这种方法主要是人工设计或者随机生成哈希函数,是一种数据独立的方法;
- 第二种是哈希学习的方法,希望从数据中自动学习出哈希函数,是一种数据依赖的方法;也是现在主流的方法;
显然第二种具有数据依赖性,是一种更有适应性的方法。
哈希学习的步骤:
- 先对原空间的样本进行降维, 得到1个低维空间的实数向量表示;
- 对得到的实数向量进行量化(即离散化)得到二进制哈希码;
量化方法:
SBQ:对于给出向量的每一个维度的数值,我们设定一个阈值。然后根据这个维度数值的情况与阈值作比较,确定其映射的二进制数是2还是1。之后我们把每个维度映射出的二进制数串起来组成哈希码。
比如某一向量为[4,3,7,8],我们设定阈值为5,并且>=5为1,反之为0.
那么该向量对应的二进制哈希码为0011.HQ:跟SBQ比较类似,是将每一个维度划分为四个区域,使用三个阈值和两位二进制码来编码。
比如一个向量为[4,3,7,8],我们设定三个阈值,2.5, 4.5, 6.5。可以把一个维度分成四个区域,每个区域分别用两位二进制码表示:00,01,10,11
那么上面的变量对应的哈希码是01011111