一、HashSet不重复原理
前提:所存储的类型已经重写了hashCode方法和equals方法
存储原理:
假设,我要将 "abc" "西瓜" "喝茶" "123" "123" ,共五个元素存入HashSet集合里,可知,要存储的类型为:String类型,通过查看String的源码可知,该类已经重写了hashSet和equals方法,我们这块主要分析它存储原理,所以直接使用即可,具体代码如下:
public static void main(String[] args) {
HashSet<String> hashSet = new HashSet<String>();
//存储: "abc" "西瓜" "喝茶" "123" "123"
hashSet.add("abc");
hashSet.add("123");
hashSet.add("西瓜");
hashSet.add("喝茶");
hashSet.add("123");
//哈希值的算法,比如abc,a对应的ASCII为:97,b-98,c-99,hashCode=97*31^2+98*31^1+99*31^0=96354
System.out.println("abc的哈希值为:"+"abc".hashCode());
System.out.println("123的哈希值为:"+"123".hashCode());
System.out.println("西瓜的哈希值为:"+"西瓜".hashCode());
System.out.println("喝茶的哈希值为:"+"喝茶".hashCode());
System.out.println("集合的大小为:"+hashSet.size()+",其中所存储的元素为:");
for(String str:hashSet) System.out.println(str);
}
结果:
那么,如何保证所存入的元素的唯一性呢?
这个时候,就要求我们必须重写所存入元素的hashCode和equals方法,通过hashCode方法得到的哈希码作为这个元素的存储地址(这个值跟地址有关,但不是实际地址),通过equals方法比较是否相同,相同则不再存储,不相同的话就会产生冲突,会产生一个链接表,将这两个元素串起来放在同一个哈希码指定的位置上,而实际上会尽量避免哈希冲突。如果直接调用equals方法,当数据量过大时,每次都会调用一次equals方法,效率低。
第一步:hashSet.add("abc"); //abc所对应的的哈希值为:96354
//在集合中查找有没有哈希值为96354的元素,发现没有,存入
第二步: hashSet.add("123"); //123对应的哈希值为:48690
//在集合中查找有没有