zoukankan      html  css  js  c++  java
  • 关于HashMap以对象作为Key的实现及踩坑

    关于HashMap以对象作为Key的实现及踩坑

    1 场景

    今天遇到了这样一串代码

    image-20211123001950011

    对于画圈的部分,看起来很奇怪,我一开始想改为:

    result.get(groupPath).add(indexes);
    groupPath.addMeasurements(exactPath.getMeasurementList());
    groupPath.addSchemas(exactPath.getSchemaList());
    

    但是却发生了大量的空指针异常

    2 原因

    查看源码后发现,HashMap以对象作为Key的时候(假设我们重写了hashcode以及equals方法),他在put和get的时候对于key部分会处理:

    • hash(key)
    • key

    image-20211123002248654

    image-20211123002303759

    换言之,在执行put的时候,HashMap会保存当前key对象的hash值引用,在get(key)的时候,会根据执行get时刻的key对象hash值进行查找,再根据引用判断相等。

    3 一个实验

    import java.util.*;
    
    public class HashMapTest {
        public static void main(String[] args) {
            Map<MyObject, List> map = new HashMap<>();
            MyObject object = new MyObject("a");
            map.put(object,new ArrayList());
            object.setName("b");
            System.out.println(map.containsKey(object));
            for (MyObject myObject : map.keySet()) {
                System.out.println(myObject.hashCode());
            }
            System.out.println(object.hashCode());
            MyObject object1 = new MyObject("a");
            System.out.println(map.containsKey(object1));
            System.out.println(object1.hashCode());
            object.setName("a");
            System.out.println(map.containsKey(object));
        }
    
        public static class MyObject{
            String name;
            MyObject (String name){
                this.name = name;
            }
    
            public void setName(String name) {
                this.name = name;
            }
    
            @Override
            public boolean equals(Object o) {
                if (this == o) return true;
                if (o == null || getClass() != o.getClass()) return false;
                MyObject myObject = (MyObject) o;
                return Objects.equals(name, myObject.name);
            }
    
            @Override
            public int hashCode() {
                return Objects.hash(name);
            }
        }
    }
    

    执行结果为:

    false
    129
    129
    false
    128
    true
    
  • 相关阅读:
    SQL查询SP代码
    MS SQL Server:查询死锁进程(转载)
    批编译、重新编译和计划缓存
    sql like获取以逗号分割的字段内的数据
    SQL Server 2005—数据库管理10个最重要的特点(转载)
    SQL2005数据库镜像配置脚本
    转:SQL 语句优化
    转:SQL SERVER什么时候写日志
    MDX查询几个经典示例
    尾日志备份和时间点还原
  • 原文地址:https://www.cnblogs.com/cpaulyz/p/15604800.html
Copyright © 2011-2022 走看看