Map面试常见问题

2023-09-14 19:44:07

Map的特点有哪些?

Java中的Map是一种接口,它表示一种将键映射到值的对象。Map的特点主要有以下几点:

  1. 键的唯一性:每个键在Map中只能出现一次,不能重复。
  2. 不保证键的顺序:Map不保证键的插入顺序或者遍历顺序。例如,HashMap在迭代时键的顺序与插入顺序可能不一致。
  3. 可以为null的键和值:Map允许使用null作为键和值。但是需要注意的是,如果使用null作为键,那么在获取值时可能会抛出NullPointerException。
  4. Map不是线程安全的:如果多个线程同时修改Map,可能会引发并发问题。如果需要线程安全的Map,可以使用ConcurrentHashMap。

Map有几种类型?

Java中的Map接口有两个主要的实现类:HashMap和TreeMap。

  1. HashMap:HashMap是一种基于哈希表的Map实现。它的主要特点是快速查询,即在给定键的情况下,能够在O(1)时间内获取对应的值。但是它不保证键的顺序。
  2. TreeMap:TreeMap是一种基于红黑树的Map实现。它的主要特点是按键的顺序存储和遍历元素。可以通过构造器传入一个自定义的Comparator来改变默认的按键顺序。

除了这两种基本的实现,Java还提供了其他一些Map的实现类,如LinkedHashMap、WeakHashMap等,它们各有自己的特点和适用场景。
在这里插入图片描述
在这里插入图片描述

​​​

HashMap数据结构是什么?

Java中的HashMap底层采用的是数组+链表(JDK1.8之前)或数组+链表+红黑树(JDK1.8之后)的数据结构。

在JDK1.8之前,HashMap内部采用数组+链表的结构来存储数据,数组是HashMap的主结构,而链表则是用来处理冲突的。当插入元素时,首先根据元素的hashCode值计算出在数组中的索引位置,如果该位置没有元素,直接将元素存储在该位置。如果有元素,则将该元素与索引位置处的元素形成链表,并比较两个元素的key值,如果key值相同,则将value值较大的元素放在链表的头,这样就可以保证每次遍历都能按照key值排序。

在JDK1.8之后,HashMap内部采用数组+链表+红黑树的结构来存储数据。当数组的长度大于一定阈值时,会将数组转化为红黑树,这样可以提高查找的效率。当红黑树的节点数量少于一定阈值时,会将红黑树转化为链表,这样可以减少树结构的维护成本。当链表的长度大于一定阈值时,会将链表转化为红黑树,这样可以保证链表在插入和删除节点时都能保持O(log n)的时间复杂度。

总之,HashMap底层的数据结构是不断优化的,以提供更好的性能和可扩展性。

HashMap是如何进行扩容的?

Java中的HashMap是一种常用的数据结构,用于存储键值对数据。HashMap的实现使用了散列(hashing)技术,通过将键转化为数组的索引,可以在O(1)的平均时间复杂度内完成数据的插入、查找和删除操作。

当HashMap中的元素数量达到一定的阈值时,就需要进行扩容操作。扩容操作的过程如下:

  1. 创建一个新的数组,其大小是原数组大小的2倍(或者更大,具体取决于Java的内存分配策略)。
  2. 使用一个新的散列函数,将原数组中的所有键值对重新散列到新数组中。
  3. 将原数组中的元素逐个复制到新数组中。
  4. 更新HashMap的内部变量,使其指向新的数组。

这个过程可能会导致CPU资源的消耗,特别是在大量数据的情况下。因此,为了保证HashMap的性能,需要合理地选择数组的大小。如果数组的大小选择过小,会导致频繁的扩容操作,影响程序的性能;如果数组的大小选择过大,会浪费内存空间。

在Java中,HashMap的扩容操作是由Java的垃圾回收机制自动完成的。当HashMap中的元素数量达到一定的阈值时,Java的垃圾回收机制会自动触发扩容操作。这个阈值是由HashMap的负载因子(load factor)决定的,负载因子是当前元素数量与数组大小的比值。当负载因子大于等于阈值时,就会触发扩容操作。默认的阈值是0.75,但是可以通过构造函数进行设置。

HashMap是线程安全的吗?

HashMap不是线程安全的。

有哪些线程安全的map?

在Java中,有几个并发安全的Map实现可以使用。以下是一些选项:

  1. ConcurrentHashMap​: 这是Java中最常用的并发安全的Map实现。它被设计为线程安全的,并且可以在多线程环境中进行无阻塞(非阻塞)操作。ConcurrentHashMap​使用分段锁机制,允许多个修改操作并行进行。
Map<String, String> map = new ConcurrentHashMap<>();
  1. Collections.synchronizedMap(HashMap)​: 这是一个包装器方法,可以将任何Map包装为线程安全的。但是,由于包装后的Map在单个操作上不是线程安全的,所以在迭代时需要外部同步。
Map<String, String> map = new HashMap<>();
Map<String, String> synchronizedMap = Collections.synchronizedMap(map);
  1. Hashtable​: 这是一个古老的线程安全的Map实现,但它的性能低于ConcurrentHashMap​。它不提供并发性,因此在多线程环境中效率低下。
Map<String, String> map = new Hashtable<>();
  1. ConcurrentSkipListMap​: 这是一个实现了NavigableMap​接口的并发Map。它提供了线程安全和并发性,并且可以进行排序操作。然而,它并不是一个完全的Map实现,因为它不支持所有的Map操作。
Map<String, String> map = new ConcurrentSkipListMap<>();

在选择并发安全的Map实现时,你应该根据你的具体需求来决定使用哪个。例如,如果你需要一个线程安全的Map,并且需要高并发性能,那么ConcurrentHashMap​可能是最好的选择。但是,如果你需要一个可以排序的线程安全的Map,那么ConcurrentSkipListMap​可能更适合你的需求。

更多推荐

【鸿蒙(HarmonyOS)】UI开发的两种范式:ArkTS、JS(以登录界面开发为例进行对比)

文章目录一、引言1、开发环境2、整体架构图二、认识ArkUI1、基本概念2、开发范式(附:案例)(1)ArkTS(2)JS三、附件一、引言1、开发环境之后关于HarmonyOS技术的分享,将会持续使用到以下版本HarmonyOS:3.1/4.0SDK:API9ReleaseNode.js:v14.20.1DevEcoS

Zookeeper应用场景和底层设计

一、什么是zookeeperZookeeper是一个开源的分布式协调服务框架,它是服务于其它集群式框架的框架。【简言之】有一个服务A,以集群的方式提供服务。只需要A专注于它提供的服务就可以,至于它如何以多台服务器协同完成任务的事情,交给Zookeeper来协调。【底层设计逻辑】1)基于观察者设计模式2)等价于文件系统+

开源项目的版本管理:Git的最佳实践

🌷🍁博主猫头虎带您GotoNewWorld.✨🍁🦄博客首页——猫头虎的博客🎐🐳《面试题大全专栏》文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺🌊《IDEA开发秘籍专栏》学会IDEA常用操作,工作效率翻倍~💐🌊《100天精通Golang(基础入门篇)》学会Golang语言,畅玩云原生,走遍大

【Rust 基础篇】Rust 模式:高效、安全和灵活的匹配工具

导言在编程中,经常需要对数据进行匹配和处理,例如从一个复杂的数据结构中提取特定的值,或者根据不同的情况执行不同的逻辑。Rust是一门现代的系统编程语言,它引入了一种称为"模式"(Pattern)的强大特性,使得数据的匹配和处理变得高效、安全和灵活。本篇博客将深入探讨Rust模式的各种用法,带您领略Rust的魅力。什么是

ES6如何声明一个类?类如何继承?

在JavaScript中,您可以使用关键字class来声明一个类。类是一种模板,用于创建对象的构造函数,其中包含了属性和方法。以下是声明一个类的基本语法:classClassName{constructor(){//构造函数,用于创建对象实例时初始化属性this.propertyName=value;}//方法定义me

stm32学习-芯片系列/选型

【03】STM32·HAL库开发-初识STM32|STM概念、芯片分类、命名规则、选型|STM32原理图设计、看数据手册、最小系统的组成、STM32IO分配_小浪宝宝的博客-CSDN博客STM32:ST是意法半导体,M是MCU/MPU,32是32位。ST累计推出了:5大类、18个系列、1000多个型号的Cortex内核

注入之mssql数据库(手工注入)

sa最高权限(可以获取系统权限)打开一个mssql数据库要拼接一个参数拼接这个参数?xxser=1检查是否是mssql数据库andexists(select*from%20sysobjects)为真是属于mssql查询当前数据库系统的用户名andsystem_user=0(由于版本问题谷歌不可以)可以去虚拟机,爆出系统

基于讯飞人脸算法(调用API进行人脸比对)

先看结果必须遥遥领先基于讯飞人脸算法视频演示所需准备这里我调用了:人脸比对API文档|讯飞开放平台文档中心https://www.xfyun.cn/doc/face/xffaceComparisonRecg/API.html#%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E代码里所涉及的APPI

联盟 | Nativex 与 HelpLook 携手助力品牌独立站实现营销增长

近日,汇量科技旗下数字营销平台Nativex与AI知识库搭建工具HelpLook携手合作,共同推动中国跨境卖家和出海开发者的数字营销和客户服务,提供更广阔的增长空间。关于Nativex&HelpLook作为一家全球数字营销平台,Nativex不仅拥有丰富的数字营销经验,还在全球范围内积累了十余年的移动营销专业知识。Na

buuctf-ciscn_s_3

一、srop参考文章-博客园-wudiiv11(作者)-BUUCTF-ciscn_2019_s_3参考文章-博客园-z2yh(作者)-Srop原理与利用方法vlun函数中没有分配栈帧(指rsp没有增长,也没有压入父函数的rbp,这也导致之后的构造payload的时候不需要填充rbp的那8个字节)首先看中间这一栏,要找b

[运维|数据库] mysql的charset与PostgreSQL的encoding

在PostgreSQL数据库中,字符集(charset)的概念与MySQL有所不同。在PostgreSQL中,字符集通常由所谓的"编码"(encoding)来表示。每个数据库都可以使用不同的编码,以适应不同的字符集需求。以下是一些常见的PostgreSQL编码及其对应的MySQL字符集的替代方式:UTF-8(Unico

热文推荐