菜鸟一枚qq_44706584 2021-10-12 11:37 采纳率: 100%
浏览 98
已结题

使用hashset的时候产生的问题

使用hashset存储两遍同一对象,但是再第二次存储之前,将该对象的一个属性值更改,然后往hashSet里存储,我以为会只有一条数据,但显示有两条数据。为什么会存进第二条数据?

img

另一个问题:
我选择打印地址不打印数据,打印出来的是我测试之前以为的一条记录。为什么打印具体数据和打印地址的结果不一样?

img

不同的只是Student类是否重写了toString():

img

求解答~

  • 写回答

5条回答 默认 最新

  • 小杨同学~ 2021-10-12 14:14
    关注

    回答你这个问题要从三个方向,让你彻底明白

    • HashSet的底层是什么?

      这个不用想吧,是HashMap,如果不确定那就看一下源码!

          public boolean add(E e) {
              return map.put(e, PRESENT)==null;
          }
      
    • Map 实现put的原则是什么?

      • key不存在直接添加
      • key存在直接覆盖value
    • Map 判断Key是否相同的逻辑是什么?

      hash值吧,不确定我们就来看看源码

          public V put(K key, V value) {
              return putVal(hash(key), key, value, false, true);
          }
      

    结合上面的分享我们就知道了,为何你修改了对象的属性,会存在两个对象了吧!究其原因是HashSet把你的实体类进行hash,实体类的值不一样了,hash值肯定不一样吧?

    为什么你说输出的地址是一样的呢?那是因为你没有重写equals方法,那就直接用的是父类的equals方法,而父类的equals 方法是用==判断的,这就引出另一个问题 ==与equals的区别了

    ==:比较两个引用是不是指向同一个对象实例,即相同的地址。

    equals:equals方法是Object类的方法,默认是直接调用==来实现。如果没有被重写,那么调用equals与==没有区别。

    如果你想清晰的看清楚,就必须重写equalshashCode的方法,这两个放过也是判断对象是否相同的重要决定性因素!

    也许你又会问,为什么我一个add方法,还需要和equals扯上关系,那么我们看看add方法的注释,如下

        /**
         * Adds the specified element to this set if it is not already present.
         * More formally, adds the specified element <tt>e</tt> to this set if
         * this set contains no element <tt>e2</tt> such that
         * <tt>(e==null&nbsp;?&nbsp;e2==null&nbsp;:&nbsp;e.equals(e2))</tt>.
         * If this set already contains the element, the call leaves the set
         * unchanged and returns <tt>false</tt>.
         *
         * @param e element to be added to this set
         * @return <tt>true</tt> if this set did not already contain the specified
         * element
         */
    

    翻译:将指定的元素添加到此集合(如果尚未存在)。 更正式地,将指定的元素e添加到此集合,如果此集合不包含元素e2 ,使得(e==null ? e2==null : e.equals(e2)) 。 如果该集合已经包含该元素,则该呼叫将保持不变,并返回false

    看完是不是恍然大悟了!希望被采纳!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 10月14日
  • 已采纳回答 10月12日
  • 创建了问题 10月12日

悬赏问题

  • ¥50 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 latex怎么处理论文引理引用参考文献
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?