java中hashmap_HashMap如何在Java中工作

java中hashmap

面试中最常见的问题是“ HashMap如何在Java中工作”,“ HashMap的获取和放置方法如何在内部工作”。 在这里,我试图通过一个简单的示例来解释内部功能。 而不是通过理论,我们将首先从示例开始,以便您可以更好地理解,然后我们将了解get和put函数如何在Java中工作。
让我们举一个非常简单的例子。 我有一个Country类,我们将使用Country类对象作为键,并使用其大写名称(字符串)作为值。 下面的示例将帮助您了解如何将这些键值对存储在哈希图中。

1. Country.java

package org.arpit.javapostsforlearning;
public class Country {String name;long population;public Country(String name, long population) {super();this.name = name;this.population = population;}public String getName() {return name;}public void setName(String name) {this.name = name;}public long getPopulation() {return population;}public void setPopulation(long population) {this.population = population;}// If length of name in country object is even then return 31(any random number) and if odd then return 95(any random number).// This is not a good practice to generate hashcode as below method but I am doing so to give better and easy understanding of hashmap.@Overridepublic int hashCode() {if(this.name.length()%2==0)return 31;else return 95;}@Overridepublic boolean equals(Object obj) {Country other = (Country) obj;if (name.equalsIgnoreCase((other.name)))return true;return false;}}

如果您想了解有关对象的哈希码和equals方法的更多信息,可以在Java中引用hashcode()和equals()方法。

2. HashMapStructure.java(主类)

import java.util.HashMap;
import java.util.Iterator;public class HashMapStructure {/*** @author Arpit Mandliya*/public static void main(String[] args) {Country india=new Country("India",1000);Country japan=new Country("Japan",10000);Country france=new Country("France",2000);Country russia=new Country("Russia",20000);HashMap<country,string> countryCapitalMap=new HashMap<country,string>();countryCapitalMap.put(india,"Delhi");countryCapitalMap.put(japan,"Tokyo");countryCapitalMap.put(france,"Paris");countryCapitalMap.put(russia,"Moscow");Iterator<country> countryCapitalIter=countryCapitalMap.keySet().iterator();//put debug point at this linewhile(countryCapitalIter.hasNext()){Country countryObj=countryCapitalIter.next();String capital=countryCapitalMap.get(countryObj);System.out.println(countryObj.getName()+"----"+capital);}}} 
</country></country,string></country,string>

现在,在第23行放置调试点,然后右键单击project-> debug as-> java应用程序。 程序将在第23行停止执行,然后右键单击countryCapitalMap,然后选择watch。您将看到以下结构。

HashMapStructure1 现在,从上图可以观察到以下几点

  1. 有一个称为table的Entry []数组,其大小为16。
  2. 该表存储Entry类的对象。 HashMap类具有一个称为Entry的内部类。此Entry具有键值作为实例变量。 让我们看一下入口类的结构Entry Structure。
  3. static class Entry implements Map.Entry
    {final K key;V value;Entry next;final int hash;...//More code goes here
    }
  4. 每当我们尝试将任何键值对放入哈希图中时,都会为键值实例化Entry类对象,并且该对象将存储在上述Entry [](表)中。 现在您一定想知道,上面创建的Enrty对象将存储在哪里(表中的确切位置)。 答案是,通过调用Hascode()方法为密钥计算哈希码。 该哈希码用于计算上述Entry []表的索引。
  5. 现在,如果您在上图中的数组索引10处看到,它具有一个名为HashMap $ Entry的Entry对象。
  6. 我们在hashmap中放置了4个键值,但似乎只有2个!!!因为这是因为如果两个对象具有相同的哈希码,则它们将存储在相同的索引处。 现在问题出现了如何? 它以LinkedList的形式存储对象(逻辑上)。

那么如何计算上述国家/地区键值对的哈希码。

Hashcode for Japan = 95 as its length is odd.
Hashcode for India =95 as its length is odd
HashCode for Russia=31 as its length is even.
HashCode for France=31 as its length is even.

下图将清楚地说明LinkedList概念。

HashMapStructure2 因此,现在,如果您对哈希图结构有很好的了解,那么让我们通过put和get方法。

放置:

让我们看一下put方法的实现:

/*** Associates the specified value with the specified key in this map. If the* map previously contained a mapping for the key, the old value is* replaced.** @param key*            key with which the specified value is to be associated* @param value*            value to be associated with the specified key* @return the previous value associated with <tt>key</tt>, or <tt>null</tt>*         if there was no mapping for <tt>key</tt>. (A <tt>null</tt> return*         can also indicate that the map previously associated*         <tt>null</tt> with <tt>key</tt>.)*/public V put(K key, V value) {if (key == null)return putForNullKey(value);int hash = hash(key.hashCode());int i = indexFor(hash, table.length);for (Entry<k , V> e = table[i]; e != null; e = e.next) {Object k;if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {V oldValue = e.value;e.value = value;e.recordAccess(this);return oldValue;}}modCount++;addEntry(hash, key, value, i);return null;}

现在让我们逐步了解上面的代码

  1. 检查键对象是否为空。 如果key为null,则它将存储在table [0]中,因为null的哈希码始终为0。
  2. 调用关键对象的hashcode()方法并计算哈希码。 该哈希码用于查找用于存储Entry对象的数组的索引。 有时可能会发生这种哈希代码函数编写不佳的情况,因此JDK设计人员放置了另一个名为hash()的函数,该函数将以上计算的哈希值作为参数。如果您想了解更多有关hash()函数的信息,可以引用hash和indexFor hashmap中的方法 。
  3. indexFor(hash,table.length)用于计算表数组中的确切索引,以存储Entry对象。
  4. 正如我们在示例中看到的那样,如果两个关键对象具有相同的哈希码(称为冲突 ),则它将以链表的形式存储。因此在这里,我们将遍历链表。
  • 如果我们刚刚计算出的那个索引上没有元素,那么它将直接将Entry对象放在那个索引上。
  • 如果该索引处存在元素,则它将迭代直到获得Entry-> next为null。然后当前的Entry对象成为该链表中的下一个节点
  • 如果我们再次放置相同的密钥,从逻辑上讲应该替换旧值该怎么办。 是的,它将这样做。在迭代时将通过调用equals()方法( key.equals(k) )检查键是否相等,如果此方法返回true,则它将值对象替换为当前Entry的值对象。

得到:

让我们看一下get get的实现:

/*** Returns the value to which the specified key is mapped, or {@code null}* if this map contains no mapping for the key.** <p>* More formally, if this map contains a mapping from a key {@code k} to a* value {@code v} such that {@code (key==null ? k==null :* key.equals(k))}, then this method returns {@code v}; otherwise it returns* {@code null}. (There can be at most one such mapping.)** </p><p>* A return value of {@code null} does not <i>necessarily</i> indicate that* the map contains no mapping for the key; it's also possible that the map* explicitly maps the key to {@code null}. The {@link #containsKey* containsKey} operation may be used to distinguish these two cases.** @see #put(Object, Object)*/public V get(Object key) {if (key == null)return getForNullKey();int hash = hash(key.hashCode());for (Entry<k , V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) {Object k;if (e.hash == hash && ((k = e.key) == key || key.equals(k)))return e.value;}return null;}

当您了解了hashmap的put功能时。 因此,了解获取功能非常简单。 如果传递任何键以从哈希图获取值对象。

  1. 检查键对象是否为空。 如果key为null,则将返回Object的值位于table [0]。
  2. 调用关键对象的hashcode()方法并计算哈希码。
  3. indexFor(hash,table.length)用于使用生成的哈希码来获取Entry对象来计算表数组中的精确索引。
  4. 在表数组中获取索引后,它将遍历链表并通过调用equals()方法检查键是否相等,如果返回true,则返回Entry对象的值,否则返回null。

记住要点:

  • HashMap有一个称为Entry的内部类,用于存储键值对。
  • 上面的Entry对象存储在称为table的Entry [](Array)中
  • 表的索引在逻辑上称为存储桶,它存储链表的第一个元素
  • 关键对象的hashcode()用于查找该Entry对象的存储桶。
  • 如果两个键对象具有相同的哈希码,则它们将进入表数组的同一存储桶中。
  • 关键对象的equals()方法用于确保关键对象的唯一性。
  • 完全不使用值对象的equals()和hashcode()方法

参考: HashMap如何在我们的JCG合作伙伴 Arpit Mandliya在Java框架和面向初学者博客的设计模式下在Java中工作 。

翻译自: https://www.javacodegeeks.com/2014/03/how-hashmap-works-in-java.html

java中hashmap

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/342915.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LoRa、Sigfox和NB-IoT在物联网趋势中谁是你的最佳拍档?

无线通信技术是物联网的传输基础&#xff0c;随着智慧城市大应用成为热门发展&#xff0c;各种技术推陈出新&#xff0c;纷纷抢占物联网市场。在LPWAN技术里&#xff0c;最热门的莫过于LoRa、Sigfox和NB-IoT。在物联网趋势中&#xff0c;这三种技术各自具有什么优势?谁才会是你…

计算机教育影片观后感,2020青少年法治教育片沉重的爱观后感大全

2020青少年法治教育片沉重的爱观后感大全时间&#xff1a;2020-11-21 13:41:01 分类&#xff1a;读/观后感 | 2020青春正步走沉重的爱观后感 | Word文档下载2020青少年法治教育片沉重的爱观后感大全导语&#xff1a;做人是孩子的立身之本&#xff0c;欲使孩子成才&#xff0c…

电话光端机类型

通过之前的介绍&#xff0c;我们了解到电话光端机就是把传统的电话信号转换成光信号并在光纤上传输的设备&#xff0c;但是&#xff0c;电话光端机又是怎么分类的&#xff0c;具体有哪些类型呢&#xff1f;今天&#xff0c;飞畅科技的小编就来为大家详细介绍下电话光端机的类型…

Zigbee如何在智能家居中成为领先的连接技术?

ZigBee技术是一种近距离、低复杂度、低功耗、低速率、低成本的双向无线通讯技术。主要用于距离短、功耗低且传输速率不高的各种电子设备之间进行数据传输以及典型的有周期性数据、间歇性数据和低反应时间数据传输的应用。 ZigBee建立在802.15.4标准之上&#xff0c;它确定了可以…

计算机启动完成后操作系统负责管理的是,终极:如果计算机启动后无法进入系统,旧驱动程序会教您如何处理...

为什么计算机无法启动进入系统&#xff1f;如何解决开机后电脑无法进入系统的问题&#xff1f;以下编辑器将为您详细介绍如何解决启动后计算机无法进入系统的问题。众所周知&#xff0c;长时间使用计算机时&#xff0c;会出现一种或另一种问题。引导后无法进入系统的问题是最常…

业界对物联网技术最常见的三大误区解读

各行各业都在借助数字化东风进行转型&#xff0c;制造业也不例外。智能工厂、大数据、物联网、人工智能……新兴技术在制造业领域焕发着巨大价值。然而对于物联网技术&#xff0c;很多企业依然抱有观望&#xff0c;甚至谨慎的态度。现在我们一起看看业界对这种技术的最常见误区…

电话光端机应用范围解析!电话光端机主要应用在哪些领域?

电话光端机刚进入安防领域时&#xff0c;称得上是当时的新贵。由于那时光纤通信的应用还未普及&#xff0c;别说行业内许多人没有看到过光端机&#xff0c;只怕没听说过的人也不在少数。那时候的光端机是十分昂贵的&#xff0c;因此也显得十分神秘。当然&#xff0c;它的性能优…

Zigbee费尽心思做mesh网究竟在智能家居中有什么用?

在物联网蓬勃发展的浪潮下&#xff0c;智能家居的热度也随之不断升温。由于智能家居的安全、节能、舒适、便利、高效等诸多特点&#xff0c;越来越多的客户开始接受和开发智能家居单品和系统。在中国推广Zigbee技术的这几年里&#xff0c;我有幸看到来自中国的厂家在物联网和智…

为什么要使用工业以太网交换机?

以太网技术得到很大的提高&#xff0c;并且被公司和大学办公室所接受&#xff0c;现在正逐步的拓展有更多需求的工业环境应用。工业以太网交换机的的吸引力包括监视数据传输&#xff0c;被用来建立和配置设备的现存实用工具 &#xff0c;还有可以从某个中心位置可以安装控制设备…

java生日快乐_Java八岁生日快乐!

java生日快乐这是又一次漫长的旅程&#xff0c;但是昨天&#xff0c;恰好是Java 7发布两年零七个月零十八天之后&#xff0c;我们现在有了可用于生产的构建 Java 8可供下载 &#xff01; 这个新的主要版本包含一些新功能和增强功能&#xff0c;这些功能和增强功能可以提高现有…

物联网在医疗保健中的应用

数字健康革命分为四个部分&#xff0c;即&#xff1a; 1、 获取信息(互联网时代) 2、 相互访问(社交网络) 3、 接触自己(通过移动和可穿戴健康技术量化自我) 4、 了解每一个人(大数据的后续开发和应用) 有趣的是&#xff0c;这实际上是由五部分组成的数字革命&#xf…

详解 | 引起电源模块发热的4个主要原因

一摸电源模块的表面&#xff0c;热乎乎的&#xff0c;模块坏了&#xff1f;且慢&#xff0c;有一点发热&#xff0c;仅仅只是因为它正努力地工作着。但高温对电源模块的可靠性影响极其大&#xff01;基于电源模块热设计的知识&#xff0c;这一次&#xff0c;我们扒一扒引起电源…

计算机表格文件打不开,我的电脑表格文件都打不开了怎么回事,请高手支个招,谢谢!...

我的电脑表格文件都打不开了怎么回事&#xff0c;请高手支个招&#xff0c;谢谢&#xff01;以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;我的电脑表格文件都打不开了怎么回事&#xff0c…

雅加达EE:干净的板岩

该公告雅加达EE不能使用javax。*名称空间是个好消息&#xff0c;并提供雅加达EE用干净的石板上构建和创新企业级Java的未来。 原始提案 可以预见&#xff0c; javax。*和jakarta。*名称空间将在Java EE 8之后共存&#xff0c;随着它的发展&#xff0c; jakarta。*名称空间将用…

电源模块低温和高温工作会造成什么后果?

现在电源模块的体积越来越小&#xff0c;功率密度也越来越高&#xff0c;并且模块的工作环境也愈发恶劣&#xff0c;其高低温设计、热设计以及应力问题逐渐引起了各位工程师的重视。电源模块的可靠性设计有何秘籍&#xff1f;本文为你揭晓。 对于一个电源模块来说&#xff0c;…

Nordic nRF52832程序下载问题分析

1.开发工具安装后无法识别芯片的问题 针对nRF52832的开发&#xff0c;首先需要下载安装对应工具&#xff0c;主要安装的工具有nRFgo Studio、Command-Line-Tools、IAR。IAR是编程者必须的工具&#xff0c;因此不做过多介绍&#xff0c;不过针对Nordic官方最新版本SDK&#xff…

【教你一招】30分钟考完广开所有科目,广开期末考试网页如何多开?

经过两天的奋战&#xff0c;不断的更新维护试题库&#xff0c;也迎接来了更多的同学使用我们的题库。 我们的客服同志也不负大家的期望&#xff0c;再次为大家找到一个强大的功能&#xff01; 支持广开2021期末浏览器多开。 短小威力大&#xff0c;我们就不废话了&#xff0c;…

电路设计之干扰问题总结与分析

在电路系统设计中&#xff0c;我们经常会遇到这样的事情&#xff0c;一个电路其程序明明是完完整整的从书上抄下来&#xff0c;试验运行结果却不正确&#xff0c;这是为什么呢&#xff0c;原因就在干扰&#xff0c;我们在进行电子电路和程序设计的过程中一定要做好抗干扰措施。…

常见的SFP光模块

说起SFP光模块&#xff0c;我们都不陌生。SFP即SMALL FORM PLUGGABLE&#xff08;小型可插拔&#xff09;的缩写&#xff0c;它是千兆以太网光模块最常使用的封装之一&#xff0c;是千兆以太网的一种行业标准。那么&#xff0c;常见的SFP光模块有哪些呢&#xff1f;接下来我们就…

无线网状网、Zigbee、RFID三种技术分析

而今&#xff0c;网络技术的发展让这一预想有机会得以实现&#xff1a;无线网状网&#xff08;又称为自组织网络&#xff09;可以构建多点对多点的网络架构、ZigBee技术完成定位感知系统、RFID技术则负责部署网络的信息节点&#xff0c;这三者的融合将实现一个无所不在的信息网…