首页 > 其他分享 >Map使用对象作key

Map使用对象作key

时间:2024-04-23 09:34:40浏览次数:20  
标签:Map xiaoMing String map 对象 key public xiaoMing2

Map介绍:

Map是一个集合,一种依照键(key)存储元素的容器,键(key)很像下标,在List中下标是整数。在Map中键(key)可以是任意类型的对象。Map中不能有重复的键(Key),每个键(key)都有一个对应的值(value);

Map的key和value都是泛型的,所以Map的key和value可以任意类型的

使用对象做Map的key会出现那些问题:

不重写HashCode方法和equals方法时:
内容相等的对象创建多次,分别调用hashCode方法获取的哈希值都是不相等的,所以HashMap中会出现相同的key对象存在;解决这个的办法对象重写HashCode方法和equals方法,使用指定的哈希算法和equals方法这样可以避免上述情况;

重写HashCode方法和equals方法出现时:
当修改已经存放在HashMap中的对象时,HashMap中key也会同步修改,但是这个key所在的哈希值还是之前的哈希值所在的位置,这样会出现,使用修改前的key查value,查到所在的位置但是调用equals方法两个key值不相等结果查不到值,使用新的key去找,会通过新的key对象的哈希值去找,两个哈希值不相等,也查不到之前的value值了,这个值永远也查不到了;

实验key对象的案例:

/**
 * 创建用户对象
 */
class User implements Serializable {

    /**
     * 姓名
     */
    public String name;
    /**
     * 身份证号
     */
    public String idCard;
    /**
     *班级
     */
    public String clazz;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getIdCard() {
        return idCard;
    }

    public void setIdCard(String idCard) {
        this.idCard = idCard;
    }

    public String getClazz() {
        return clazz;
    }

    public void setClazz(String clazz) {
        this.clazz = clazz;
    }

    public static void main(String[] args) {
        //创建用户对象做key的HashMap集合
        HashMap<User, String> map = new HashMap<>();
        /**
         * 创建小明用户对象
         * 存放到map中
         */
        User xiaoMing = new User();
        xiaoMing.setName("小明");
        xiaoMing.setIdCard("4243124");
        xiaoMing.setClazz("二班小明");
        map.put(xiaoMing,"xiaoMing");
        System.out.println("xiaoMing的哈希值:"+xiaoMing.hashCode());

        /**
         * 在重新新建小明对象
         * 存放到map中
         */
        User xiaoMing2 = new User();
        xiaoMing2.setName("小明");
        xiaoMing2.setIdCard("4243124");
        xiaoMing2.setClazz("二班小明");
        map.put(xiaoMing2,"xiaoMing2");
        System.out.println("xiaoMing2的哈希值:"+xiaoMing2.hashCode());
        for (User user : map.keySet()) {
            System.out.println(map.get(user));
        }

    }

}

运行结果(控制台输出了两个小明对象):

 原因HashMap是通过key的哈希值去放的元素的

 

解决上述问题方式:

用户实体类中重写equals方法和hashCode方法或者使用Lombok中的@EqualsAndHashCode注解;

/**
 * 创建用户对象
 */
//@EqualsAndHashCode
class User implements Serializable {

    /**
     * 姓名
     */
    public String name;
    /**
     * 身份证号
     */
    public String idCard;
    /**
     *班级
     */
    public String clazz;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getIdCard() {
        return idCard;
    }

    public void setIdCard(String idCard) {
        this.idCard = idCard;
    }

    public String getClazz() {
        return clazz;
    }

    public void setClazz(String clazz) {
        this.clazz = clazz;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return name.equals(user.name) && idCard.equals(user.idCard) && clazz.equals(user.clazz);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, idCard, clazz);
    }

    /**
     * main方法测试
     * @param args
     */
    public static void main(String[] args) {
        //创建用户对象做key的HashMap集合
        HashMap<User, String> map = new HashMap<>();
        /**
         * 创建小明用户对象
         * 存放到map中
         */
        User xiaoMing = new User();
        xiaoMing.setName("小明");
        xiaoMing.setIdCard("4243124");
        xiaoMing.setClazz("二班小明");
        map.put(xiaoMing,"xiaoMing");
        System.out.println("xiaoMing的哈希值:"+xiaoMing.hashCode());

        /**
         * 在重新新建小明对象
         * 存放到map中
         */
        User xiaoMing2 = new User();
        xiaoMing2.setName("小明");
        xiaoMing2.setIdCard("4243124");
        xiaoMing2.setClazz("二班小明");
        map.put(xiaoMing2,"xiaoMing2");
        System.out.println("xiaoMing2的哈希值:"+xiaoMing2.hashCode());
        for (User user : map.keySet()) {
            System.out.println(map.get(user));
        }

    }

}

重写之后的结果(map中只有一个元素了):

 

重写之后有出现新的问题:

再次修改map中key的对象之后将永久获取不到之前的值了;

如果再次保存的话也不会覆盖之前的元素只会新增一个元素如下实验;

/**
 * 创建用户对象
 */
class User implements Serializable {

    /**
     * 姓名
     */
    public String name;
    /**
     * 身份证号
     */
    public String idCard;
    /**
     *班级
     */
    public String clazz;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getIdCard() {
        return idCard;
    }

    public void setIdCard(String idCard) {
        this.idCard = idCard;
    }

    public String getClazz() {
        return clazz;
    }

    public void setClazz(String clazz) {
        this.clazz = clazz;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return name.equals(user.name) && idCard.equals(user.idCard) && clazz.equals(user.clazz);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, idCard, clazz);
    }

    /**
     * main方法测试
     * @param args
     */
    public static void main(String[] args) {
        //创建用户对象做key的HashMap集合
        HashMap<User, String> map = new HashMap<>();
        /**
         * 创建小明用户对象
         * 存放到map中
         */
        User xiaoMing = new User();
        xiaoMing.setName("小明");
        xiaoMing.setIdCard("4243124");
        xiaoMing.setClazz("二班小明");
        map.put(xiaoMing,"xiaoMing");
        System.out.println("xiaoMing的哈希值:"+xiaoMing.hashCode());
        xiaoMing.setClazz("三班小明");
        map.put(xiaoMing,"三班小明");
        System.out.println("三班xiaoMing的哈希值:"+xiaoMing.hashCode());
        map.get(xiaoMing);

        /**
         * 在重新新建小明对象
         * 存放到map中
         */
        User xiaoMing2 = new User();
        xiaoMing2.setName("小明");
        xiaoMing2.setIdCard("4243124");
        xiaoMing2.setClazz("二班小明");
        map.put(xiaoMing2,"xiaoMing2");
        System.out.println("xiaoMing2的哈希值:"+xiaoMing2.hashCode());
        for (User user : map.keySet()) {
            System.out.println(map.get(user));
        }

    }

}

运行数据时

 结果如下:

 

原因是因为修改了key对象之后同步修改了之前的key但是map存储时使用key是之前的key存放的元素 所以就找不到之前的元素了

而且使用keySet循环查也找不到之前的数据了 就是因为使用新key的哈希值和之前的不一样造成的

 

结语

谢谢观看,如有疑问欢迎留言,上面的验证和解析可能有错误之处,欢迎留言指导。

转自:https://blog.csdn.net/weixin_47628154/article/details/125132888

标签:Map,xiaoMing,String,map,对象,key,public,xiaoMing2
From: https://www.cnblogs.com/shijianchuzhenzhi/p/18152139

相关文章

  • keycloak~使用jwks验证token的合法性
    keycloak提供了jwks服务,其地址可以在/auth/realms/fabao/.well-known/openid-configuration的返回结果中找到,jwks_uri它表示了公钥的颁发者,可以使用颁发出来的公钥来验证token的签名,基地址也是固定的/auth/realms/fabao/protocol/openid-connect/certs。springboot构建keycloak的......
  • ASP.NET Core Web API下基于Keycloak的多租户用户授权的实现
    在上文《Keycloak中授权的实现》中,以一个实际案例介绍了Keycloak中用户授权的设置方法。现在回顾一下这个案例:服务供应商(ServiceProvider)发布/WeatherForecastAPI供外部访问在企业应用(Client)里有三个用户:super,daxnet,nobody在企业应用里有两个用户组:administrators,users在企......
  • SnakeYaml反序列化分析
    前言SnakeYaml是Java中解析yaml的库,而yaml是一种人类可读的数据序列化语言,通常用于编写配置文件等。yaml真是到哪都有啊。环境搭建<dependency><groupId>org.yaml</groupId><artifactId>snakeyaml</artifactId><version>1.32</version></dependency>SPI机制介绍......
  • MIT6824 MapReduce总结
    MapReduce是一个分布式大任务计算框架,旨在可以方便Google内部的将大型任务拆分到集群环境下,以得到并行化的处理速度。在分布式情况下,多台机器协作完成一个大型任务需要考虑很多问题:整个分布式系统中都有哪些角色?可以预见的就是肯定有任务的拆分者负责拆分调度任务,有任务的实际......
  • Spring中将@RequestParam绑定到对象(转)
    译文:https://blog.csdn.net/dnc8371/article/details/106810876/译文作者:dnc8371来源:CSDN原文:https://www.javacodegeeks.com/2018/10/how-bind-requestparam-object-spring.html您是否在请求映射方法中用@RequestParam注释了多个参数,并认为它不可读?当请求中需要一个或两个输......
  • 深度解读《深度探索C++对象模型》之数据成员的存取效率分析(三)
    接下来我将持续更新“深度解读《深度探索C++对象模型》”系列,敬请期待,欢迎关注!也可以关注公众号:iShare爱分享,自动获得推文和全部的文章列表。前面两篇请通过这里查看:深度解读《深度探索C++对象模型》之数据成员的存取效率分析(一)深度解读《深度探索C++对象模型》之数据成员的......
  • Integer超过128要用对象比较,否则出问题
    一、测试代码publicvoidtestEquals(){intint1=12;intint2=12;Integerinteger1=newInteger(12);Integerinteger2=newInteger(12);Integerinteger3=newInteger(127);Integera1=127;//或者写成Integera1=Integ......
  • sqlmap简单使用方法
    基本格式sqlmap-u"http://www.vuln.cn/post.php?id=1"默认使用level1检测全部数据库类型sqlmap-u"http://www.vuln.cn/post.php?id=1" --dbmsmysql--level3指定数据库类型为mysql,级别为3(共5级,级别越高,检测越全面)cookie注入当程序有防get注入的时候,可以使用cookie注......
  • 记录:Flask 框架中,g对象的生命周期
    在Flask框架中,g对象是一个特殊的全局对象,它的设计目的是为了在不同的请求处理函数之间共享数据,但不需要将数据存储在session或数据库中。g对象的生命周期与当前的请求/响应周期紧密相关。以下是g对象生命周期的要点:创建:当一个请求到达Flask应用时,g对象会被创建并初始......
  • 【js】两个数组对象合并成一个树结构的数据
    1模板2/**3*合并两个数组,将岗位信息按照部门进行分组4*@param{Array}array1岗位信息数组,每个岗位包含部门ID(deptId)、岗位ID(postId)和岗位名称(postName)5*@param{Array}array2部门信息数组,每个部门包含部门ID(id)和部门名称(label)6*@returns{Arr......