Kotlin HashMap remove失效 get失效问题

30 篇文章 0 订阅
1 篇文章 0 订阅

Kotlin HashMap remove失效 get失效问题

由于最近转向大Google的Kotlin,使用感受非常好,推荐!但是今天竟然被HashMap折磨了。遇到问题记录如下。

什么问题

在使用一个HashMap集合时候,remove有时候能够成,有时候失败。get同理。
debug查看,竟然3个一样的key能够存在于map中。多年来的经验告诉我。map有重复的key是覆盖操作啊!
Debug图

粗糙的解决

花一个小时,部分类切换回JAVA,发现没有错误了,一开始我以为是kotlin集合的锅,顺便骂了谷歌几遍娘。解决问题了就好。作为一个有抱负的程序员决定追究一下问题。

HashMap源码跟进
public V remove(Object key) {
        Node<K,V> e;
        return (e = removeNode(hash(key), key, null, false, true))
    }
static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

简单的分析

HashMap的一个节点是Node对象,reomove也是调用removeNode,Node与HashMap关联又是强依赖哈希值,hash值不一样的话,就当成两个节点处理了。具体见其他HashMap源码分析

刚刚跟进去remove就大概明白了,

有时候人就是容易转牛角尖,好多次了,再次提醒自己,遇到问题还是要先冷静分析,不能想到一些方法就去干。

HashMap 为什么Kotlin有问题,Java没问题。
  • JAVA
    谁没事不会去重写Object的hashcode()函数,如标准库String,Integer…为了效率可能会重写。基本上所有自定义的类使用的都是系统默认的hash算法。native函数,物理内存地址根据特定算法转换而成的数字。
  • Kotlin
    由于data class的存在, 出现了问题根本!data class kotlin为了 数据类而设计的一个语法糖,会自动重写许多函数。equals,toString…等等,当然也包括hashcode函数。当一个dataclass对象有一些可变参数的时候,参数改变hash值就改变,但是之前put到hashmap里面的node已经绑定了之前的hash。所以remove找不到node!
   /**
    *一个三个参数(int,String,String)的类声明成dataclass hashcode重写为如下
    */
 public int hashCode() {
      int var10000 = this.int * 31;
      String var10001 = this.str;
      var10000 = (var10000 + (var10001 != null ? var10001.hashCode() : 0)) * 31;
      var10001 = this.str2;
      return var10000 + (var10001 != null ? var10001.hashCode() : 0);
   }

把data class 改为class 就解决了。。没什么特别需要 别使用data class使用尽量也使用val声明参数。浪费内存又浪费青春,背锅!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值