当前位置: 首页 > news >正文

Java-详解HashMap

图片描述

哈希表定义:根据设定的hash函数和处理冲突的方式(开放定址、公共溢出区、链地址、重哈希...)将一组关键字映射到一个有限的连续的地址集上(即bucket数组或桶数组),并以关键字在地址集中的“像”作为记录在表中的存储位置,这种表称为hash表;这一映射过程称为散列,所得存储位置称为哈希地址或散列地址。

一、定义

HashMap实现了Map接口,继承AbstractMap。其中Map接口定义了键映射到值的规则,而AbstractMap类提供 Map 接口的骨干实现,以最大限度地减少实现此接口所需的工作。

图片描述

public class HashMap<K,V>
    extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable

二、构造函数

HashMap提供了三个构造函数:

  • HashMap():构造一个具有默认初始容量 (16) 和默认加载因子 (0.75) 的空 HashMap。

  • HashMap(int initialCapacity):构造一个带指定初始容量和默认加载因子 (0.75) 的空 HashMap。

  • HashMap(int initialCapacity, float loadFactor):构造一个带指定初始容量和加载因子的空 HashMap。

容量表示哈希表中桶的数量,初始容量是创建哈希表时的容量; 装载因子:loadfactor = 表中填入的记录数/哈希表的长度

所以loadfactor标志着哈希表的装满程度,直观的看,装载因子越小,发生冲突的概率越小(因为桶中还没装几个数据,就需要扩容),也就是查找性能越好,但同时浪费的空间就变大。相反,装载因子越大,发生冲突的概率越大(等到桶快填满时才能扩容,比如,采用链表法处理冲突,在此种情况下,会导致链表过长),查找性能越差,同时浪费的空间会减少。

三、数据结构

我们知道在Java中最常用的两种结构是数组和模拟指针(引用),几乎所有的数据结构都可以利用这两种来组合实现,HashMap也是如此。实际上HashMap是一个“链表散列”(数组和链表的结合体)。

图片描述
可见,HashMap底层实现还是数组(横行),只是数组的每一项(纵列)都是一条链。Entry为HashMap的内部类,它包含了键key、值value、下一个节点next,以及hash值,这是非常重要的,正是由于Entry才构成了table数组的项为链表。


总结

*1.HashMap的默认大小为16,即桶数组的默认长度为16;
2.HashMap的默认装载因子是0.75;
3.HashMap内部的桶数组存储的是Entry对象,也就是键值对对象。
4.构造器支持指定初始容量和装载因子,为避免数组扩容带来的性能问题,建议根据需求指定初始容量。装载因子尽量不要修改,0.75是个比较靠谱的值。
5.桶数组的长度始终是2的整数次方(大于等于指定的初始容量),这样做可以减少冲突概率,提高查找效率。(可以从indexfor函数中看出,h&(length-1),若length为奇数,length-1为偶数那么h&(length-1)结果的最后一位必然为0,也就是说所有键都被散列到数组的偶数下标位置,这样会浪费近一半空间。另外,length为2的整数次方也保证了h&(length-1)与h%length等效).
6.HashMap接受null键;
7.HashMap不允许键重复,但是值是可以重复的。若键重复,那么新值会覆盖旧值。
8.HashMap通过链表法解决冲突问题,每个Entry都有一个next指针指向下一个Entry,冲突元素(不是键相同,而是hash值相同)会构成一个链表。并且最新插入的键值对始终位于链表首部。
9.当容量超过阈值(threshold)时,会发生扩容,扩容后的数组是原数组的两倍。扩容操作需要开辟新数组,并对原数组中所有键值对重新散列,非常耗时。我们应该尽量避免HashMap扩容。
10.HashMap非线程安全。*

相关文章:

  • Web 仪表盘
  • ORM
  • 【转载】Java NIO学习 NIO BIO AIO 比较
  • highcharts 使用实例
  • linux中ctime,mtime,atime的区别
  • Oozie Coordinator 规范
  • 深入分析Parquet列式存储格式
  • sed指令
  • Mongodb 通过一致性备份搭建SECONDARY.
  • 手把手教使用WebStorm搭建ExtJs5开发环境
  • 国内某公有云 linux云主机开机初始化过程分析和他的镜像制作过程
  • [Todo] C++学习资料进度
  • 词法分析器报告
  • httpclient 认证方式访问http api/resutful api并获取json结果
  • 2015年Java开发岗位面试题归类
  • 《Javascript高级程序设计 (第三版)》第五章 引用类型
  • 【跃迁之路】【463天】刻意练习系列222(2018.05.14)
  • 【跃迁之路】【699天】程序员高效学习方法论探索系列(实验阶段456-2019.1.19)...
  • classpath对获取配置文件的影响
  • CSS居中完全指南——构建CSS居中决策树
  • Date型的使用
  • FastReport在线报表设计器工作原理
  • JavaScript设计模式与开发实践系列之策略模式
  • Java精华积累:初学者都应该搞懂的问题
  • MySQL Access denied for user 'root'@'localhost' 解决方法
  • React Native移动开发实战-3-实现页面间的数据传递
  • React系列之 Redux 架构模式
  • tweak 支持第三方库
  • Vue2.0 实现互斥
  • 给github项目添加CI badge
  • 扑朔迷离的属性和特性【彻底弄清】
  • 首页查询功能的一次实现过程
  • 算法系列——算法入门之递归分而治之思想的实现
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (1综述)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (Ruby)Ubuntu12.04安装Rails环境
  • (ZT) 理解系统底层的概念是多么重要(by趋势科技邹飞)
  • (安卓)跳转应用市场APP详情页的方式
  • (超详细)语音信号处理之特征提取
  • (经验分享)作为一名普通本科计算机专业学生,我大学四年到底走了多少弯路
  • (理论篇)httpmoudle和httphandler一览
  • (一) storm的集群安装与配置
  • (转)JVM内存分配 -Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=512m
  • .Net 垃圾回收机制原理(二)
  • .net对接阿里云CSB服务
  • @DateTimeFormat 和 @JsonFormat 注解详解
  • [100天算法】-x 的平方根(day 61)
  • [④ADRV902x]: Digital Filter Configuration(发射端)
  • [BZOJ] 1001: [BeiJing2006]狼抓兔子
  • [C++]:for循环for(int num : nums)
  • [C++]类和对象【上篇】
  • [Dxperience.8.*]报表预览控件PrintControl设置
  • [Excel VBA]单元格区域引用方式的小结