HashSet不重复主要add方法实现,使用add方法查找是否有元素,如果存在则不添加,如果不存在则不添加不存在,会添加的。HashSet主要是基于HashMap实现的。HashMap的键是HashSet的元素。HashSet是基于哈希函数实现元素不重复的。先看add方法:publicbooleanadd(Ee){returnmap.put(e,PRESENT)==null;}HashMap的put方法,map的put方法调用了putVal方法。publicVput(Kkey,Vvalue){returnputVal(hash(key),key,value,false,true);}hash方法是计算hash值,右移16位^使hash分布更均衡staticfinalinthash(Objectkey){inth;返回(键==空)?0:(h=key.hashCode())^(h>>>16);}查看putVal方法:/***实现了Map.put和相关方法。**@paramhash键的哈希值*@paramkey键*@paramvalue要放置的值*@paramonlyIfAbsent如果为真,则不更改现有值*@paramevict如果为假,表处于创建模式。*@returnpreviousvalue,ornullifnone*/finalVputVal(inthash,Kkey,Vvalue,booleanonlyIfAbsent,booleanevict){Node[]tab;节点p;诠释n,我;//如果table为null,则展开table数组if((tab=table)==null||(n=tab.length)==0)n=(tab=resize()).length;//在tab数组的位置找不到元素,直接添加元素if((p=tab[i=(n-1)&hash])==null)tab[i]=newNode(hash,key,value,null);//标签数组中有一个元素else{Nodee;;//如果hash值相同,key也相同,说明原位置的key和现在插入的key相同,直接替换if(p.hash==hash&&((k=p.key)==key||(key!=null&&key.equals(k))))e=p;//值类型为TreeNode,导入红黑树,红黑树不存在,直接添加存在则替换elseif(pinstanceofTreeNode)e=((TreeNode)p).putTreeVal(this,tab,hash,key,value);else{for(intbinCount=0;;++binCount){if((e=p.next)==null){p.next=newNode(hash,key,value,null);if(binCount>=TREEIFY_THRESHOLD-1)//-1对于第一个treeifyBin(tab,hash);休息;}if(e.hash==hash&&((k=e.key)==key||(key!=null&&key.equals(k))))中断;p=e;}}if(e!=null){//键VoldValue=e.value的现有映射;如果(!onlyIfAbsent||oldValue==null)e.value=value;节点访问后(e);返回旧值;}}++模数;如果(++大小>阈值)调整大小();节点插入后(逐出);//如果原key不存在,则返回nullreturnnull;ifnone返回之前的值,不存在则返回null。通过源码分析:查找tab数组中是否有元素。如果该元素不存在,则直接创建一个节点。如果存在,则保存原始值。判断原值是否为空。如果不存在则返回原值为空,返回null总结HashSet主要利用了哈希算法的唯一性,每个元素的哈希值都是唯一的。哈希码不同,说明该元素不存在。如果存储数据的哈希码相同,equles判断为equal,说明该元素已经存在。如果没有数据,哈希码相同,equles判断不相等,说明该元素不存在。这里的equles是直接调用存储数据源码中Object的equles方法,也就是比较内存地址。但是在实际调用中,会使用String或者Integer等封装类型,这些类型会覆盖equals方法。这是我一开始不理解的地方。如果您觉得文章对您有帮助,请点个赞吧!