HashSet存储数据原理:
HashSet作为Set的主要实现类,其存储的是无序的、不可重复的数据。
(1)无序性:不等于随机性。存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的哈希值
(2)不可重复性:保证添加的元素按照equals( )判断时,不能返回true,即:相同的元素只能添加一个
如果要向HashSet中添加元素a,首先HashSet会调用元素a所在类的hashCode()方法,计算元素a的哈希值,接着通过算法计算出此哈希值在HashSet底层数组中的存放位置,判断此位置上是否有元素:
如果此位置上没有其它元素则添加成功;
如果此位置已经有其他元素b(或以链表形式存放着多个元素),则比较元素a与元素b的hash值:
如果hash值不同,则添加成功;
如果hash值不同,则需要进一步调用元素a所在类的equals()方法:
equals()返回true,元素a添加失败
接下来通过一道例题来直观的理解一下HashSet底层存储机制:
//最终输出结果为多少?
import java.util.HashSet;
public class Hashset {
public static void main(String[] args) {
Hashset s = new Hashset();
s.test();
}
public void test() {
HashSet set = new HashSet();
Person p1 = new Person("AA");
Person p2 = new Person("BB");
set.add(p1);
set.add(p2);
p1.setName("CC");
set.remove(p1);
System.out.println(set);
}
}//注:默认Person类以创建
此题最终输出结果应为:CC BB;
此题最容易误以为输出结果是BB。最开始HashSet存放p1时,是按照AA的哈希值对应的位置来存放的,接下来p1所包含的属性由AA替换成了CC;进行删除p1操作时,首先会计算出p1里所包含属性的哈希值,再通过一定算法找到其哈希值对应存放的位置,进而删除。但此时p1所包含的属性已经由AA变成了CC,CC的哈希值与AA的哈希值不一样,那么所对应的存储位置也就不同,在删除时就会在CC的哈希值所对应的存储位置进行删除操作,就不能删除p1所在的位置上的属性。