就是一个十进制整数。是通过Object类的hashCode()方法获得:int hashCode();
默认Object类的hashCode的方法返回的哈希值是该对象在内存中的地址值。
哈希值是对象存储到哈希表的重要依据。
哈希表的存储过程
哈希表的存储过程(存取原理):每存入一个新的元素都要走以下五步
(1)调用对象的hashCode()方法,获得要存储元素的哈希值。
(2)将哈希值与表的长度(即数组的长度)进行求余运算得到一个整数值,该值就是新元素要存放的位置(即是索引值)。
如果索引值对应的位置上没有存储任何元素,则直接将元素存储到该位置上。
如果索引值对应的位置上已经存储了元素,则执行第3步。
(3)遍历该位置上的所有旧元素,依次比较每个旧元素的哈希值和新元素的哈希值是否相同。
如果有哈希值相同的旧元素,则执行第4步。
如果没有哈希值相同的旧元素,则执行第5步。
(4)比较新元素和旧元素的地址是否相同
如果地址值相同则用新的元素替换老的元素。停止比较。
如果地址值不同,则新元素调用equals方法与旧元素比较内容是否相同。
如果返回true,用新的元素替换老的元素,停止比较。
如果返回false,则回到第3步继续遍历下一个旧元素。
(5)说明没有重复,则将新元素存放到该位置上并让新元素记住之前该位置的元素。
问题:为什么存储字符串的时候,字符串内容相同的只存储了一个呢?
通过查看add方法的源码,我们知道这个方法底层依赖 两个方法:hashCode()和equals()。
步骤:
首先比较哈希值
如果相同,继续走,比较地址值或者走equals()
如果不同,就直接添加到集合中
按照方法的步骤来说:
先看hashCode()值是否相同
相同:继续走equals()方法
返回true: 说明元素重复,就不添加
返回false:说明元素不重复,就添加到集合
不同:就直接把元素添加到集合
如果类没有重写这两个方法,默认使用Object()的方法。
而String类重写了hashCode()和equals()方法,所以,它就可以把内容相同的字符串去掉。只留下一个。
public static void main(String[] args) { // 创建集合对象 HashSet<String> hs = new HashSet<String>(); // 创建并添加元素 hs.add("hello"); hs.add("world"); hs.add("java"); hs.add("world"); hs.add("hello"); hs.add("world"); hs.add("java"); hs.add("world"); print(hs); } public static <E> void print(Collection<E> link) { // 遍历 for (E s : link) { System.out.println(s); } System.out.println("--------------------------"); // 遍历集合,获取得到每一个元素 Iterator<E> it = link.iterator(); while (it.hasNext()) { E s = it.next(); System.out.println(s); } System.out.println("--------------------------"); }