返回顶部
首页 > 资讯 > 后端开发 > Python >Java如何根据key值修改Hashmap中的value值
  • 874
分享到

Java如何根据key值修改Hashmap中的value值

Javakey值Java修改Hashmap的value值JavaHashmapvalue值 2023-03-22 20:03:26 874人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录根据key值修改HashMap的value值HashMap的key更改后能否正确获取value?测试案例总之最后根据key值修改Hashmap的value值 如果原来map中没有

根据key值修改Hashmap的value值

如果原来map中没有key,会创建,如果原来有key,会使用value 覆盖掉原来的值

map.put(key,value);

这个实现对原值加一(前提是有这个key)

map.put(key,map.get(key)+1);

以下可以获取key对应的value,如果没有可以返回默认的value

map.getOrDefault(key,value);

HashMap的key更改后能否正确获取value?

在HashMap 中存放的一系列键值对,其中键为某个我们自定义的类型。放入 HashMap 后,我们在外部把某一个 key 的属性进行更改,然后我们再用这个 key 从 HashMap 里取出元素,这时候 HashMap 会返回什么?

我们办公室几个人答案都不一致,有的说返回null,有的说能正常返回value。但不论答案是什么都没有确凿的理由。我觉得这个问题挺有意思的,就写了代码测试。结果是返回null。需要说明的是我们自定义的类重写了 hashCode 方法。我想这个结果还是有点意外的,因为我们知道 HashMap 存放的是引用类型,我们在外面把 key 更新了,那也就是说 HashMap 里面的 key 也更新了,也就是这个 key 的 hashCode 返回值也会发生变化。这个时候 key 的 hashCode 和 HashMap 对于元素的 hashCode 肯定一样,equals也肯定返回true,因为本来就是同一个对象,那为什么不能返回正确的值呢?

测试案例

这里有 2 个案例,一个是 Person 类,还有一个是 Student 类,我们来验证下以上的观点(附带结论):

  • 修改了对象属性是否会改变它的 hashcode => 是的
  • 在 HashMap 里存取的时候是否会受到修改属性影响取值 => 取值为 null
package tech.luxsun.interview.luxinterviewstarter.collection;
 
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.HashMap;
 

public class MapDemo0 {
 
    public static void main(String[] args) {
        HashMap<Object, Object> map = new HashMap<>();
 
        // Person Case
        Person p = new Person("Bob", 12);
        map.put(p, "person");
        System.out.println(p.hashCode());
        System.out.println(map.get(p));
 
        p.setAge(13);
        System.out.println(p.hashCode());
        System.out.println(map.get(p));
 
        // Student Case
        Student stu = new Student("Bob", 12);
        map.put(stu, "student");
        System.out.println(stu.hashCode());
        System.out.println(map.get(stu));
 
        stu.setAge(13);
        System.out.println(stu.hashCode());
        System.out.println(map.get(stu));
    }
}
 
@Data
@AllArgsConstructor
@NoArgsConstructor
class Person {
    private String name;
    private Integer age;
 
    public int hashCode() {
        return 123456;
    }
}
 
@Data
@AllArgsConstructor
@NoArgsConstructor
class Student {
    private String name;
    private Integer age;
}

输出结果

123456
person
123456
person
71154
student
71213
null

源码

hashCode 源码

public int hashCode() {
    int PRIME = true;
    int result = 1;
    Object $age = this.getAge();
    int result = result * 59 + ($age == null ? 43 : $age.hashCode());
    Object $name = this.getName();
    result = result * 59 + ($name == null ? 43 : $name.hashCode());
    return result;
}

map.get 源码


public V get(Object key) {
    node<K,V> e;
    return (e = getNode(hash(key), key)) == null ? null : e.value;
}
 
 

static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
 

final Node<K,V> getNode(int hash, Object key) {
    Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
    if ((tab = table) != null && (n = tab.length) > 0 &&
        (first = tab[(n - 1) & hash]) != null) {
        if (first.hash == hash && // always check first node
            ((k = first.key) == key || (key != null && key.equals(k))))
            return first;
        if ((e = first.next) != null) {
            if (first instanceof TreeNode)
                return ((TreeNode<K,V>)first).getTreeNode(hash, key);
            do {
                if (e.hash == hash &&
                    ((k = e.key) == key || (key != null && key.equals(k))))
                    return e;
            } while ((e = e.next) != null);
        }
    }
    return null;
}

总之

可以看到先取得了一个table,这个table实际上是个数组。然后在table里面找对应 key 的value。找的标准就是hash等于传入参数的hash, 并且满足另外两个条件之一:k = e.key,也就是说他们是同一个对象,或者传入的 key 的equal目标的 key 。我们的问题出在那个hash(key.hashCode()),可以看到 HashMap 在存储元素时是把 key 的 hashCode 再做了一次hash。得到的hash将最终作为元素存储位置的依据。对应到我们的情况:第一次存储时,hash函数采用key.hashCode作为参数得到了一个值,然后根据这个值把元素存到了某个位置。

当我们再去取元素的时候,key.hashCode的值已经出现了变化,所以这里的hash函数结果也发生了变化,所以当它尝试去获得这个 key 的存储位置时就不能得到正确的值,导致最终找不到目标元素。要想能正确返回,很简单,把Person类的 hashCode 方法改一下,让它的 hashCode 不依赖我们要修改的属性,但实际开发中肯定不能这么干,我们总是希望当两个对象的属性不完全相同时能返回不同的 hashCode 值。

所以结论就是当把对象放到 HashMap 后,不要去修改 key 的属性,除非你重写了该实体类的 hashCode 方法不受属性限制。

最后

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: Java如何根据key值修改Hashmap中的value值

本文链接: https://lsjlt.com/news/200940.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Java如何根据key值修改Hashmap中的value值
    目录根据key值修改Hashmap的value值HashMap的key更改后能否正确获取value?测试案例总之最后根据key值修改Hashmap的value值 如果原来map中没有...
    99+
    2023-03-22
    Java key值 Java修改Hashmap的value值 Java Hashmap value值
  • Java怎么根据key值修改Hashmap中的value值
    这篇文章主要讲解了“Java怎么根据key值修改Hashmap中的value值”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java怎么根据key值修改Hashmap中的value值”吧!根...
    99+
    2023-07-05
  • 如何在java中使用enum根据value值获取key键
    这篇文章主要介绍了如何在java中使用enum根据value值获取key键,编程网小编觉得不错,现在分享给大家,也给大家做个参考,一起跟随编程网小编来看看吧!Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编程语言的...
    99+
    2023-06-06
  • Map集合中如何获取key-value值
    这篇文章主要介绍“Map集合中如何获取key-value值”,在日常操作中,相信很多人在Map集合中如何获取key-value值问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Map集合中如何获取key-val...
    99+
    2023-07-05
  • java中如何获取map的key值
    在Java中,可以使用`Map`的`keySet()`方法获取`Map`的所有key值。`keySet()`方法返回一个`Set`集...
    99+
    2023-08-31
    java
  • jquery如何根据id改变元素值
    本篇内容主要讲解“jquery如何根据id改变元素值”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“jquery如何根据id改变元素值”吧! ...
    99+
    2024-04-02
  • php如何改变数组key的值
    这篇文章主要讲解了“php如何改变数组key的值”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“php如何改变数组key的值”吧!两种改变方法:1、使用array_values()函数重置数组...
    99+
    2023-07-02
  • java如何获取object中某key的值
    在Java中,可以通过以下方式获取object中某个key的值: 使用JSONObject类:首先将object转换为JSONOb...
    99+
    2023-10-24
    java object
  • java map中相同的key保存多个value值方式
    目录map中相同的key保存多个value值如下代码Map中相同的键Key不同的值Value实现原理实现原理总结map中相同的key保存多个value值 在java中,Map集合中只...
    99+
    2024-04-02
  • java如何修改list里面的值
    要修改List中的值,可以通过调用set方法来实现。例如,如果要将List中第一个元素修改为新的值,可以使用以下代码: List&l...
    99+
    2024-04-02
  • SAP MM MM17里不能修改物料主数据'Purchasing Value Key'字段值?
    SAP MM MM17里不能修改物料主数据'Purchasing Value Key'字段值?记得在D项目上线之前数据导入系统之后,业务提出一些物料采购视图里的’Purchasing value key’字段需要修改一下。&...
    99+
    2023-06-05
  • java如何修改静态变量的值
    要修改Java中的静态变量的值,可以直接通过类名来访问静态变量并赋值。例如: public class Example { ...
    99+
    2024-04-02
  • jquery如何修改select的选中值
    这篇“jquery如何修改select的选中值”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇...
    99+
    2024-04-02
  • vue2.0如何根据状态值进行样式改变
    这篇文章主要介绍vue2.0如何根据状态值进行样式改变,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!用户在进行流程操作的时候,一般分为进行中,未开始,已完成,前端页面就要进行相应的状...
    99+
    2024-04-02
  • php数据库如何修改某值
    这篇文章主要为大家展示了“php数据库如何修改某值”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“php数据库如何修改某值”这篇文章吧。php数据库修改某值的方法:1、选择要操作的数据库并连接;2...
    99+
    2023-06-22
  • javascript如何修改td的值
    这篇“javascript如何修改td的值”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“j...
    99+
    2024-04-02
  • jquery如何修改button的值
    这篇“jquery如何修改button的值”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“j...
    99+
    2024-04-02
  • jquery如何修改td的值
    这篇“jquery如何修改td的值”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“jquer...
    99+
    2024-04-02
  • golang中如何修改一个值
    Golang 是一种十分流行的编程语言,其简洁的语法、高性能以及并发特性,使得它在 Web 应用、网络编程等领域有着广泛的运用。在 Go 中,修改一个变量的值可能不太容易理解,本文将详细介绍 Go 中如何修改一个值。1. 值传递和引用传递在...
    99+
    2023-05-14
  • jquery如何修改select选中值
    今天小编给大家分享一下jquery如何修改select选中值的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一、修改选项我们可...
    99+
    2023-07-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作