我的编程空间,编程开发者的网络收藏夹
学习永远不晚

如何进行Java中对HashMap的深度分析与比较

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

如何进行Java中对HashMap的深度分析与比较

如何进行Java中对HashMap的深度分析与比较,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

在Java的世界里,无论类还是各种数据,其结构的处理是整个程序的逻辑以及性能的关键。由于本人接触了一个有关性能与逻辑同时并存的问题,于是就开始研究这方面的问题。

 这里就拿HashMap来研究吧。
  
  HashMap可谓JDK的一大实用工具,把各个Object映射起来,实现了“键--值”对应的快速存取。但实际里面做了些什么呢?

  在这之前,先介绍一下负载因子和容量的属性。大家都知道其实一个 HashMap 的实际容量就 因子*容量,其默认值是 16×0.75=12; 这个很重要,对效率很一定影响!当存入HashMap的对象超过这个容量时,HashMap 就会重新构造存取表。这就是一个大问题,我后面慢慢介绍,反正,如果你已经知道你大概要存放多少个对象,最好设为该实际容量的能接受的数字。

  两个关键的方法,put和get:

  先有这样一个概念,HashMap是声明了 Map,Cloneable, Serializable 接口,和继承了 AbstractMap 类,里面的 Iterator 其实主要都是其内部类HashIterator 和其他几个 iterator 类实现,当然还有一个很重要的继承了Map.Entry 的 Entry 内部类,由于大家都有源代码,大家有兴趣可以看看这部分,我主要想说明的是 Entry 内部类。它包含了hash,value,key 和next 这四个属性,很重要。put的源码如下

  public Object put(Object key, Object value) {
  Object k = maskNull(key);

  这个就是判断键值是否为空,并不很深奥,其实如果为空,它会返回一个static Object 作为键值,这就是为什么HashMap允许空键值的原因。

  int hash = hash(k);
  int i = indexFor(hash, table.length);

  这连续的两步就是 HashMap 最牛的地方!研究完我都汗颜了,其中 hash 就是通过 key 这个Object的 hashcode 进行 hash,然后通过 indexFor 获得在Object table的索引值。

  table???不要惊讶,其实HashMap也神不到哪里去,它就是用 table 来放的。最牛的就是用 hash 能正确的返回索引。其中的hash算法,我跟JDK的作者 Doug 联系过,他建议我看看《The art of programing vol3》可恨的是,我之前就一直在找,我都找不到,他这样一提,我就更加急了,可惜口袋空空啊!!!

  不知道大家有没有留意 put 其实是一个有返回的方法,它会把相同键值的 put 覆盖掉并返回旧的值!如下方法彻底说明了 HashMap 的结构,其实就是一个表加上在相应位置的Entry的链表:

  for (Entry e = table[i]; e != null; e = e.next) {
  if (e.hash == hash && eq(k, e.key)) {
  Object oldvalue = e.value;
  e.value = value; //把新的值赋予给对应键值。
  e.recordAccess(this); //空方法,留待实现
  return oldvalue; //返回相同键值的对应的旧的值。
  }
  }
  modCount++; //结构性更改的次数
  addEntry(hash, k, value, i); //添加新元素,关键所在!
  return null; //没有相同的键值返回
  }

  我们把关键的方法拿出来分析:

  void addEntry(int hash, Object key, Object value, int bucketIndex) {
  table[bucketIndex] = new Entry(hash, key, value, table[bucketIndex]);

  因为 hash 的算法有可能令不同的键值有相同的hash码并有相同的table索引,如:key=“33”和key=Object g的hash都是-8901334,那它经过indexfor之后的索引一定都为i,这样在new的时候这个Entry的next就会指向这个原本的table[i],再有下一个也如此,形成一个链表,和put的循环对定e.next获得旧的值。到这里,HashMap的结构,大家也十分明白了吧?

  if (size++ >= threshold) //这个threshold就是能实际容纳的量
  resize(2 * table.length); //超出这个容量就会将Object table重构

  所谓的重构也不神,就是建一个两倍大的table(我在别的论坛上看到有人说是两倍加1,把我骗了),然后再一个个indexfor进去!注意!!这就是效率!!如果你能让你的HashMap不需要重构那么多次,效率会大大提高!

  说到这里也差不多了,get比put简单得多,大家,了解put,get也差不了多少了。对于collections我是认为,它是适合广泛的,当不完全适合特有的,如果大家的程序需要特殊的用途,自己写吧,其实很简单。(作者是这样跟我说的,他还建议我用LinkedHashMap,我看了源码以后发现,LinkHashMap其实就是继承HashMap的,然后override相应的方法,有兴趣的同人,自己looklook)建个 Object table,写相应的算法,就ok啦。

  举个例子吧,像 Vector,list 啊什么的其实都很简单,最多就多了的同步的声明,其实如果要实现像Vector那种,插入,删除不多的,可以用一个Object table来实现,按索引存取,添加等。

  如果插入,删除比较多的,可以建两个Object table,然后每个元素用含有next结构的,一个table存,如果要插入到i,但是i已经有元素,用next连起来,然后size++,并在另一个table记录其位置。

关于如何进行Java中对HashMap的深度分析与比较问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网行业资讯频道了解更多相关知识。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

如何进行Java中对HashMap的深度分析与比较

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

如何进行Java中对HashMap的深度分析与比较

如何进行Java中对HashMap的深度分析与比较,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。在Java的世界里,无论类还是各种数据,其结构的处理是整个程序的逻辑以及性能
2023-06-03

Java中对HashMap的深度分析与比较(转)

Java中对HashMap的深度分析与比较(转)[@more@]在Java的世界里,无论类还是各种数据,其结构的处理是整个程序的逻辑以及性能的关键。由于本人接触了一个有关性能与逻辑同时并存的问题,于是就开始研究这方面的问题。找遍了大大小小的
2023-06-03

如何进行malloc/free与new/delete的对比分析

今天给大家介绍一下如何进行malloc/free与new/delete的对比分析。文章的内容小编觉得不错,现在给大家分享一下,觉得有需要的朋友可以了解一下,希望对大家有所帮助,下面跟着小编的思路一起来阅读吧。相同点:都可用于申请动态内存和释
2023-06-17

如何进行Rails和Django的深度技术对比

这篇文章将为大家详细讲解有关如何进行Rails和Django的深度技术对比 ,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。我想以一个免责声明来开始下面的内容。我使用Django开发网站已经有
2023-06-17

如何对网站的SEO优化进行多角度分析

这篇文章主要介绍如何对网站的SEO优化进行多角度分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!  在进行seo优化的过程中,我们还要对各种情况都进行合理的分析,真正的去认识到整个网站的一些情况,这样在今后优化过程
2023-06-10

如何进行网站开发中转化率比较低的解决方法分析

如何进行网站开发中转化率比较低的解决方法分析,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。网站转化率低的一些表现,主要分析网站的转化率低的一些情况,这些情况大家应该都遇到过,但
2023-06-12

在 PHP 中,如何根据数组值的比较对数组进行排序?

php 中对数组进行排序的方法有:使用 sort() 函数升序排列。使用 rsort() 函数降序排列。使用 asort() 函数为关联数组升序排列值。使用 arsort() 函数为关联数组降序排列值。使用自定义比较函数进行更复杂的排序。如
在 PHP 中,如何根据数组值的比较对数组进行排序?
2024-05-03

在Golang中,如何将泛型类型的接口与nil进行比较?

哈喽!今天心血来潮给大家带来了《在Golang中,如何将泛型类型的接口与nil进行比较?》,想必大家应该对Golang都不陌生吧,那么阅读本文就都不会很困难,以下内容主要涉及到,若是你正在学习Golang,千万别错过这篇文章~希望能帮助到你
在Golang中,如何将泛型类型的接口与nil进行比较?
2024-04-04

如何进行Java Mybatis中的Mapper原理分析

如何进行Java Mybatis中的Mapper原理分析,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。准备1.pom文件
2023-06-26

Android知识体系梳理(4)-Java基础篇-Object方法分析,String的深度解析,String Pool分析,与StringBuilder、StringBuffer的对比

五、Object的方法介绍和String解析 有的同学要问了,Object和String是我们这一块儿日常一直在使用的东西,为什么要单独拎出来讲呢?其实,他们使用起来虽然简单,但比如Object类是位于java.lang包中的,java.l
2022-06-06

如何进行java面向对象编程原理的分析

这期内容当中小编将会给大家带来有关如何进行java面向对象编程原理的分析,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Java 的核心是面向对象编程。事实上,所有的Java 程序都是面向对象的,你别无选择
2023-06-03

Java如何使用用户自定义的比较函数对数组中的键名进行排序

Java中可使用Arrays.sort()方法对数组键名进行自定义排序。首先创建自定义比较函数,实现Comparator接口的compare()方法,指定键名大小比较逻辑。然后在Arrays.sort()中传入自定义比较函数作为参数。该方法将按指定逻辑对键名进行排序。示例代码展示了按忽略大小写顺序排序键名的过程。通过自定义比较函数,可根据特定需求对键名进行灵活排序。
Java如何使用用户自定义的比较函数对数组中的键名进行排序
2024-04-02

Java如何使用用户定义的比较函数按值对数组进行排序

Java中使用用户自定义比较函数按值对数组进行排序。实现Comparator接口定义自定义比较方法。通过Arrays.sort()方法使用比较函数排序数组。灵活、可扩展、可复用。替代方案包括:实现Comparable接口、匿名内部类、lambda表达式。
Java如何使用用户定义的比较函数按值对数组进行排序
2024-04-02

phpcms中如何对网站流量进行统计和分析?(在phpcms中,应如何进行网站流量的统计与分析工作?)

phpCMS中网站流量统计与分析指南:集成第三方工具(谷歌分析、百度统计等)利用PHPCMS内置功能(网站统计图表、访问统计等)设置统计代码,配置统计设置,授予访问权限分析流量数据(流量概况、来源、页面表现等)利用洞察力优化网站(提升流量、优化内容、改善体验)提示:定期查看、使用过滤器、结合不同工具、考虑外部因素。
phpcms中如何对网站流量进行统计和分析?(在phpcms中,应如何进行网站流量的统计与分析工作?)
2024-04-02

如何进行Java中对象与表单的自动装配

这期内容当中小编将会给大家带来有关如何进行Java中对象与表单的自动装配,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。时下很多 Web 框架 都实现了 Form 表单域与 Java 对象属性的自动装配功能
2023-06-17

如何进行Java任务队列的定义与代码的分析

如何进行Java任务队列的定义与代码的分析,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Java任务队列需要我们详细的学习,当然我们在不断的使用中还需要注意相关信息的学习。
2023-06-17

如何进行Java中守护线程的分析及使用

这篇文章跟大家分析一下“如何进行Java中守护线程的分析及使用”。内容详细易懂,对“如何进行Java中守护线程的分析及使用”感兴趣的朋友可以跟着小编的思路慢慢深入来阅读一下,希望阅读后能够对大家有所帮助。下面跟着小编一起深入学习“如何进行J
2023-06-26

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录