范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

通过源码探查HashSet究竟是如何保证唯一性的

  面试官: 你能简单介绍下List和Set有什么区别吗?
  小憨: List是一个有序的集合,在内存是连续存储的,可以存储重复的元素,List查询快,增删慢; Set是一个无序的集合,在内存中不连续,不可以存储重复的元素,Set增删快,查询慢;
  面试官: 那HashSet是如何保证元素不重复的?
  小憨: 3分钟…
  为了避免出现小憨这种知其然不知其所以然的尴尬,我们还是有必要来分析下上述问题的。
  客官,且看下文
  我们都知道HashSet存放的元素是不允许重复的,那么HashSet又是是如何保证元素不可重复的,你知道吗?
  先看段源码 public class HashSet     extends AbstractSet     implements Set, Cloneable, java.io.Serializable {     static final long serialVersionUID = -5024744406713321676L;      private transient HashMap map;      private static final Object PRESENT = new Object();      public HashSet() {         map = new HashMap<>();     }           public HashSet(Collection<? extends E> c) {         map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));         addAll(c);     }           public HashSet(int initialCapacity, float loadFactor) {         map = new HashMap<>(initialCapacity, loadFactor);     } }
  乍一看这段代码,哎呦我去,new HashSet()操作不就不是维护了一个HashMap嘛,要是这么往下演的话,我觉得我这点功力也能看个大概呀!
  诸位同仁,咱接着往下看 public boolean add(E e) {     return map.put(e, PRESENT)==null; }
  什么,这不就是map操作么,瞬间我来个下饭推理;
  Map中的key是不允许重复的,而你HashSet正好利用我Map中key不重复的特性来校验重复元素,妙哉妙哉。
  确实,HashSet确实是利用Map的这一特性实现了元素的不重复特性,但是我们再来深挖一下,Map他又是如何来保证key不重复的呢?
  与其说这篇文章是介绍HashSet如何保证元素不重复的,倒不如说Map是如何保证Key不重复的。 final V putVal(int hash, K key, V value, boolean onlyIfAbsent,                    boolean evict) {         Node[] tab; Node p; int n, i;         if ((tab = table) == null || (n = tab.length) == 0)             n = (tab = resize()).length;                      // 1、如果该位置不存在,直接插入         if ((p = tab[i = (n - 1) & hash]) == null)             tab[i] = newNode(hash, key, value, null);         else {             Node e; K k;             // 2、如果存在,判断是否是重复元素             if (p.hash == hash &&                 ((k = p.key) == key || (key != null && key.equals(k))))                 e = p;             else if (p instanceof TreeNode)                 e = ((TreeNode)p).putTreeVal(this, tab, hash, key, value);             else {                 for (int binCount = 0; ; ++binCount) {                     if ((e = p.next) == null) {                         p.next = newNode(hash, key, value, null);                         if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st                             treeifyBin(tab, hash);                         break;                     }                     if (e.hash == hash &&                         ((k = e.key) == key || (key != null && key.equals(k))))                         break;                     p = e;                 }             }             if (e != null) { // existing mapping for key                 V oldValue = e.value;                 if (!onlyIfAbsent || oldValue == null)                     e.value = value;                 afterNodeAccess(e);                 return oldValue;             }         }         ++modCount;         if (++size > threshold)             resize();         afterNodeInsertion(evict);         return null;     }
  上面部分我重点圈了两段代码,分别是1和2。
  第一段 if ((p = tab[i = (n - 1) & hash]) == null)
  这段代码其实主要是通过hash计算该元素的位置,然后判断该位置是否有值,如果没有值,那么可以直接插入,最后返回null;
  第二段 if (p.hash == hash &&                 ((k = p.key) == key || (key != null && key.equals(k))))                 e = p;
  如果通过计算,该位置上已经有其他元素,那么接下来就会通过hash和equals进行判断,判断它是不是重复元素,如果重复元素,那么最后会将这个重复元素返回。
  通过第二段代码我们可以发现,判断元素是否重复,使用的是hash和equals方法进行判断的,所有我们Set里面如果存放的是对象,那么一定要重写hash和equals方法。
  现在是不是很清晰了,为啥要重写equals方法了,不会出现那么诡异的代码了,这两个对象值都一样啊,为什么Set没去重呢!

历代信徒,向峨嵋舍身崖下投掷的金银还在么?揭秘崖下的诡秘世界峨眉山作为佛教的四大名山之一,更是举世闻名的普贤菩萨道场,其佛教文化拥有的悠长历史底蕴,使得众多善男信女,都前来参拜。峨眉山金顶佛光再加上峨眉山神奇的金顶佛光,让不少信徒为之向往,下午3点,国乒26岁世界冠军造大冷门,球迷伤心,刘国梁该出手了3月13日消息,wtt大满贯比赛正在紧张地进行中,今天比赛进入到第三个比赛日,本次大满贯比赛的规格很高,国乒派出全部主力男女队共计16名队员参赛,国乒的目标非常清晰,就是要拿到本次新生代童星出身演员刘依悦写真公开俏皮灵动童趣十足新生代童星出身演员刘依悦写真公开俏皮灵动童趣十足近日,新生代演员刘依悦的一组最新写真释出。在公开的这一组写真中,刘依悦绑着干净清爽的马尾,身穿浅蓝色印花毛衣,在游乐园里拿着泡泡机显又见柏阿姨和黄飞珏介绍旅游线路,对不友好网友言辞犀利毫不示弱柏阿姨自从离开电视台新老娘舅节目之后,一心一意地打理自己的工作室。办相亲节目牵头组织团体旅游,忙得不亦乐乎。最近柏阿姨又和老搭档黄飞珏,联合了某旅行社开辟了一条全新的旅游景点。秉承湖人秃曼巴回归,戴维斯回到家乡为什么会交易戴维斯,尽管老詹最近对阵勇士和奇才分别砍下56分50分但是这样的数据对于球队目前29胜37负,位于西部第九距第八相差6个胜场,基本上是徒劳的。单凭詹姆斯天神下凡,才能艰乘坐电动游览观光车旅游需要注意什么?休闲的时候到景区旅游是现下比较流行的娱乐方式,随着各大景区不断引入轨道小火车来吸引游客的关注,现在景区游览观光车品种繁多,以轨道小火车为首的游览观光项目络绎不绝。许多人在投资景区轨微型小行星Sar2593今日撞击地球距离天文台发现仅2小时北京时间3月12日凌晨3点24分,也就是大多数人还在睡梦中的时候,一颗此前尚未被发现的小行星被监测到要撞击地球。所幸的是,这颗小行星并不会产生太大的破坏力,它的宽度在12米,在当天小时候怕鬼人知鬼恐怖,鬼晓人心毒。小时候怕鬼,因为面部狰狞,长大后怕人,尽是衣冠禽兽,我怕鬼,鬼却未伤我分毫,我真心对人,却让我遍体鳞伤。最可怕的不是鬼,而是人心的丑陋,社会的险恶。这是现实加拿大留学生春假旅游攻略要点1)多伦多及周边旅游攻略2)温哥华樱花节旅游攻略3)维多利亚旅游攻略4)蒙特利尔旅游攻略5)埃德蒙顿旅游攻略6)卡尔加里旅游攻略现在正是大地复苏万物争春的好时节,也是出游的大好华为天才少年稚晖君自制硬萌机器人,开源5小时,GitHub收获317星编辑桃子拉燕新智元导读失踪人口回归了!华为天才少年稚晖君这次带来了一个又萌又硬的桌面小机器人ElectronBot。还记得上次那个全栈自研的给葡萄缝针的钢铁侠机械臂Dummy吗?近CBA官方许钟豪违反体育运动精神停赛6场罚款20万直播吧3月13日讯CBA官方刚刚宣布,重罚许钟豪,停赛6场外加罚款20万!CBA公告原文如下各CBA俱乐部2022年3月12日,20212022赛季CBA联赛常规赛第三十四轮场序3
十大高薪行业和十大低薪行业行业薪资排名十大高薪职业1证券,月5。6万。2游戏,月2。95万。3银行,月2。89万。4半导体设备,月2。71万。5航运港口,月2。35万。6生物制药,月2。27万。7集成电脑与2022年服贸会观察双碳目标成关键词绿色创新技术集中亮相在国家双碳战略背景下,绿色创新成为2022年中国国际服务贸易交易会(以下简称服贸会)的突出亮色。与往年不同,今年服贸会国家会议中心会场新设16700平方米环境服务专题展,绿色服务的吉林建设1个都市圈,3个城镇聚集区,4个发展轴带,有望赶超天津吉林,地处中国东北地区中部,是我国重要的工业基地和商品粮生产基地。近年来,在经济上处于一个低谷阶段,留不住人。即使拥有吉林大学这样的全国一流高校,每年毕业生大部分都会选择南方,这也油价调整消息今天9月8日,调价后全国9295号汽油新售价油价每吨跌240元,今天9月8日,调价后全国9295号汽油新售价今天9月8日,最新消息显示,油价在当前的预计跌幅达到240元吨,轻松碾压油价在9月7日凌晨的上调190185元吨,与导致锦州银行负债过多,坏账激增的原因是什么?一锦州银行内部原因(一)负债来源高度依赖同业业务锦州银行与大部分中小银行一样,近几年都在追逐资产规模的快速扩张,一边依靠高速发展的同业负债来支撑业务发展,另一方面为追求更高收益扩大油价调整信息今天9月8号,国内加油站调整后9295号汽油价格今天是2022年9月8日,国内成品油价格第十八次调整周期正常运行,截至目前,汽柴油价格调整了十七次,经历了十一次上调,六次上调。整个来说,汽柴油分别上涨15951535元吨(约为1有多少存款才可以彻底躺平?经济下行社会固化,越来越多的人纹丝不动,开始向往躺平的生活。那么,到底有多少钱才能彻底躺平呢?有人说,100万,500万,1000万。其实没人能预料。90年代,很多人认为有1万块钱俄气宣布,中俄天然气交易就用本币,考虑购买更多人民币头号周刊据中石油网站发布消息称,中国石油集团董事长和俄罗斯天然气工业股份公司董事长,已经举行了视频会议,双方共同决定,接下来中俄的天然气交易将使用人民币或卢布结算。(中石油和俄天然三星GalaxyS23弥补短板,4500mAh5。9英寸,打造尖端小屏旗舰手机随着全面屏时代的到来,小屏幕手机越来越少了,主流手机的屏幕尺寸基本都在6。5英寸以上,想要买到一款6英寸以下的小屏手机,眼下看来只有iPhone13mini可以选择,但是它的缺点过华为手机可以卫星发短信,是否是一招另有内涵的杀招呢现在外界普遍用本能的思考反应,认为,华为手机上卫星,是顺理成章,水到渠成的,普通得不能再普通的一招了,并没有针对第三方的意思,只是自已在努力拯救自已而已。其实我也是这么认为的,我觉盘点ColorOS13上备受好评的功能,这五个都很实用日前,ColorOS13正式发布,新系统采用了全新的水生设计理念,在系统流畅性界面设计互联等多个方面都带来了升级。想必不少O粉已经用上了ColorOS13公测版,看到网上也好评不断