1.HashMap的数据结构
数组的特点是:寻址容易,插入和删除困难;而链表的特点是:寻址困难,插入和删除容易。那么我们能不能综合两者的特性,做出一种寻址容易,插入删除也容易的数据结构?答案是肯定的,这就是我们要提起的哈希表,哈希表有多种不同的实现方法,我接下来解释的是最常用的一种方法—— 拉链法,我们可以理解为“链表的数组” ,如图:
从上图我们可以发现哈希表是由数组+链表组成的,一个长度为16的数组中,每个元素存储的是一个链表的头结点。那么这些元素是按照什么样的规则存储到数组中呢。一般情况是通过hash(key)%len获得,也就是元素的key的哈希值对数组长度取模得到。比如上述哈希表中,12%16=12,28%16=12,108%16=12,140%16=12。所以12、28、108以及140都存储在数组下标为12的位置。
HashMap其实也是一个线性的数组实现的,所以可以理解为其存储数据的容器就是一个线性数组。这可能让我们很不解,一个线性的数组怎么实现按键值对来存取数据呢?这里HashMap有做一些处理。
1.首先HashMap里面实现一个静态内部类Entry,其重要的属性有 key , value, next,从属性key,value我们就能很明显的看出来Entry就是HashMap键值对实现的一个基础bean,我们上面说到HashMap的基础就是一个线性数组,这个数组就是Entry[],Map里面的内容都保存在Entry[]里面。
2.HashMap的存取实现
既然是线性数组,为什么能随机存取?这里HashMap用了一个小算法,大致是这样实现:
//存储时: int hash = key.hashCode();// 这个hashCode方法这里不详述,只要理解每个key的hash是一个固定的int值 int index = hash % Entry[].length; Entry[index] = value; //取值时: int hash = key.hashCode(); int index = hash % Entry[].length; return Entry[index];
到这里我们轻松的理解了HashMap通过键值对实现存取的基本原理
3.疑问:如果两个key通过hash%Entry[].length得到的index相同,会不会有覆盖的危险?
这里HashMap里面用到链式数据结构的一个概念。上面我们提到过Entry类里面有一个next属性,作用是指向下一个Entry。打个比方, 第一个键值对A进来,通过计算其key的hash得到的index=0,记做:Entry[0] = A。一会后又进来一个键值对B,通过计算其index也等于0,现在怎么办?HashMap会这样做:B.next = A,Entry[0] = B,如果又进来C,index也等于0,那么C.next = B,Entry[0] = C;这样我们发现index=0的地方其实存取了A,B,C三个键值对,他们通过next这个属性链接在一起。所以疑问不用担心。也就是说数组中存储的是最后插入的元素。到这里为止,HashMap的大致实现,我们应该已经清楚了。
当然HashMap里面也包含一些优化方面的实现,这里也说一下。比如:Entry[]的长度一定后,随着map里面数据的越来越长,这样同一个index的链就会很长,会不会影响性能?HashMap里面设置一个因素(也称为因子),随着map的size越来越大,Entry[]会以一定的规则加长长度。
3.解决hash冲突的办法
- 开放定址法(线性探测再散列,二次探测再散列,伪随机探测再散列)
- 再哈希法
- 链地址法
- 建立一个公共溢出区
Java中hashmap的解决办法就是采用的链地址法。
相关推荐
在前端开发中,数据结构和算法的高效使用对于优化代码性能至关重要。`HashMap`作为一种常见的数据结构,它在JavaScript中的应用广泛,...同时,`README.md`文件通常会提供安装、使用和贡献指南,是初识项目的好起点。
7. **集合框架**:ArrayList、LinkedList、HashSet、HashMap等容器的理解和使用,学习它们的增删改查操作及适用场景。 8. **接口与抽象类**:理解接口的定义和实现,抽象类的作用,以及两者之间的区别。 9. **多...
6. **数组与集合框架**:数组是存储固定数量同类型元素的数据结构,而集合框架(如ArrayList、LinkedList、HashSet、HashMap等)提供了更加灵活的数据组织方式。学习如何创建、添加、删除和遍历这些数据结构。 7. *...
例如,`java.util`包包含了各种实用工具类,如ArrayList和HashMap。 异常处理是Java中的重要组成部分,通过try-catch-finally语句块来捕获和处理运行时错误。这有助于提高程序的健壮性,防止因未预见的情况导致程序...
此外,Java还提供了丰富的标准库,如集合框架(ArrayList、HashMap等)、I/O流、网络编程API等。 接着,Spring框架是Java企业级应用的基石。它提供了一个全面的基础设施,支持开发和配置可测试、松耦合的Java应用。...
【初识Java】 Java是一种广泛使用的面向对象的编程语言,由Sun Microsystems(后被Oracle公司收购)于1995年发布。它的设计目标是具备“简单性、面向对象、健壮性、安全性、可移植性、高效性、多线程和动态性”等...
- **集合框架**:ArrayList、LinkedList、HashMap等是Java中的常用数据结构,用于存储和操作数据。 - **IO流**:用于读写文件,网络通信等,包括字节流和字符流。 - **多线程**:Java内置对多线程的支持,通过...
hashmap源码 AAA_JAVA 6月30 初识java 各种缩写 SE-->Standard Edition标准版写桌面程序 ME-->Micro Edition微机版写嵌入式 EE-->enterprise edition企业版写服务器 JVM-->Java Virtual Machine虚拟机 ...
hashmap源码 eclipse 快捷键 eclipse 中 导 包 的快捷键ctrl + shift + o , 也可以用ctrl + 1 来修复 即, 当java文件中因为没有导入文件报错时, 直接ctrl + shift + o 来修复 eclipse 中自动生成get 、set 、...
- 集合框架:Java提供了丰富的集合类,如ArrayList、LinkedList、HashMap等,用于存储和操作对象。 本文档“初识Java_第18页_下载资料.pdf”可能涵盖了以上部分或全部内容,帮助初学者建立起对Java语言的基础认识,...
在这一章,你将学习ArrayList、LinkedList、HashSet、HashMap等常见集合类的用法,以及它们之间的区别和选择。同时,还会涉及泛型和迭代器的概念,这些都是处理集合数据的关键。 第五章:IO与NIO 输入/输出(IO)和...
第一讲“初识Java”是入门的基础,涵盖了Java的历史背景、特点、应用领域以及Java开发环境的搭建,包括JDK(Java Development Kit)的安装和配置,以及如何编写第一个"Hello, World!"程序,让初学者了解Java编程的...
学生将学习如何声明和操作数组,以及使用ArrayList、LinkedList、HashSet、HashMap等集合类。 5. **字符串处理**:字符串在编程中非常常见,Java的String类提供了丰富的操作方法,如拼接、查找、替换等。 6. **...
5. **数组与集合框架**:讲解一维和多维数组,以及集合接口(如List、Set、Map)和实现类(如ArrayList、LinkedList、HashSet、HashMap)的使用。 其次,可能深入到Java的进阶主题: 6. **IO流**:探讨如何进行...
初识Java部分,主要介绍了Java的发展历程、应用领域以及与其他编程语言的区别,帮助读者建立对Java的基本认知。 接下来,书中逐步深入到Java语法的核心,如数据类型和运算符。这部分内容涵盖了基本数据类型、引用...
5. **chapter2**:初识Java,可能包含基本语法,如变量声明、数据类型、运算符、流程控制(if、for、while)等,以及简单的函数和方法。 6. **chapter36**:可能涉及的是输入/输出流的更深入话题,如对象序列化或...
3. **HashMap和HashSet**:HashMap存储键值对,HashSet存储不重复元素,它们都依赖于哈希算法。 4. **接口和抽象类的区别**:接口只定义方法,不能有实例变量;抽象类可以有实例变量,可以提供部分实现。 ### 其他...
11. **基本设计模式**:初识设计模式,如单例模式、工厂模式和观察者模式,这些都是软件开发中常用的设计模式,有助于编写可扩展和可维护的代码。 在学习过程中,实践是关键。通过编写简单的程序,逐步加深对这些...
6. **集合框架**:学习ArrayList、LinkedList、HashSet、HashMap等集合类的使用。 7. **多线程**:理解并发编程,创建和管理线程,以及同步机制如synchronized关键字和wait/notify机制。 8. **网络编程**:讲解...
4. **集合框架**:熟悉ArrayList、LinkedList、HashSet、HashMap等集合类的使用,理解它们的内部实现和适用场景。 5. **输入/输出流**:学习如何使用Java I/O流进行文件操作,包括读写文件、处理网络流等。 6. **...