获取对象的hash值使用:
对象名.hashCode()方法。
当我们直接打印对象名时,我们说是打印的是对象的地址值。其实,Java中地址值实际上是假的,实际上是哈希值的16进制。
如果我们转换一下,发现对象的hashcode和对面打印出的“地址值”是一样的。
在Java中,是有实际真实的地址值的,只不过调用tostring()方法,将他转换成哈希值的16进制返回了。
在object类中的tostring()方法:
getClass().getName() + '@' + Integer.toHexString(hashCode())
toHexString()就是返回16进制的方法。
比较哈希表元素唯一,要分为两步:
第一就是我们在类里的比较哈希值,第二是判断元素内容:equals()方法。
如果正常情况下,得到的hashCode不同,内容也不同,那么元素添加不会有重复的。因为set是无序不重复的。
但是,如果是不同的对象结果呢,例如我我新建一个自定义类User,类里只有姓名和密码。不重写其他方法。可以重写ToString().
HashSet<User> user=new HashSet<>();
user.add(new User("姓名1",密码1));
user.add(new User("姓名2",密码2));
user.add(new User("姓名1",密码1));
当匿名创建多个对象时,对象不同,那么肯定他的HashCode也不相同.对象没有重写,那么他比较的是地址值,结合上面说的,既然比较地址值,那么得出的equals也是不一样的。结果就出来了。
会出现添加了两个姓名1,密码1.
解决的方法就是我们用到的:
override:
使用哈希表结构保存自定义类型时,为了保证元素的唯一性,
必须重写自定义类型中的hashCode和equals方法
通过重写,会先比较添加的内容,通过内容来判断hash值,
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Test test = (Test) o;
return age == test.age &&
name.equals(test.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
看下面的那个hashcode(),是通过姓名和年龄,也就姓名和密码来得出哈希值的,内容一样,得出的hashcode也是一样的,那么就不可以添加到set集合中!!
也就确定了集合中元素的唯一!