首页 > 编程语言 >Java集合框架详解:List、Set、Map及其实现类的使用与特性 第三章

Java集合框架详解:List、Set、Map及其实现类的使用与特性 第三章

时间:2024-04-03 15:32:27浏览次数:19  
标签:Map 顺序 Java HashMap 插入 Set 键值 线程

目录

一、Java Map接口及其常见实现类

Map接口定义与特性

HashMap

TreeMap

LinkedHashMap

Hashtable与ConcurrentHashMap


一、Java Map接口及其常见实现类

Map接口定义与特性

Map接口是Java集合框架中的一个重要接口,它提供了一种键值对(Key-Value Pair)的存储结构。Map的主要特点和特性包括:

  1. 键值对存储:Map中的每个元素都包含一个唯一的键(Key)和与之关联的值(Value)。键和值可以是任何非null的对象,但键必须唯一,即一个Map中不能有两个相同的键。

  2. 键唯一:Map通过键来访问与其关联的值,因此键必须具有良好的散列性(对于HashMap等基于哈希表的实现)或可比较性(对于TreeMap等基于排序树的实现)。当尝试插入或替换具有相同键的新元素时,旧值将被覆盖。

  3. 常用方法:Map接口提供了丰富的操作方法,如put(key, value)插入键值对、get(key)通过键获取值、remove(key)删除键值对、containsKey(key)检查是否存在指定键、size()返回元素数量等。此外,还有clear()清空Map、isEmpty()检查是否为空、keySet()获取所有键组成的Set视图、values()获取所有值组成的Collection视图、entrySet()获取所有键值对组成的Set视图等。

  4. 遍历方式

    • 迭代器遍历:通过调用entrySet().iterator()获取迭代器,然后使用hasNext()next()遍历所有键值对。每个键值对以Map.Entry<K, V>形式呈现,可以访问其getKey()getValue()等方法。
    • 增强for循环遍历:使用for (Map.Entry<K, V> entry : map.entrySet())语句遍历所有键值对。
    • Stream API遍历:Java 8及以上版本引入了Stream API,可通过map.entrySet().stream()创建键值对的Stream,进而进行链式操作(如过滤、映射、聚合等)。

HashMap

HashMap是Map接口最常用的实现类之一,其基于哈希表(Hash Table)实现。特点和适用场景如下:

  1. 实现原理:HashMap内部使用数组+链表/红黑树(Java 8引入)的数据结构。每个键值对存储在一个称为桶(Bucket)的结构中,通过键的哈希码(hashCode)确定其在数组中的索引。当多个键哈希到同一个桶时,形成链表或红黑树(当链表长度超过阈值时转换为树)。

  2. 优点

    • 查找速度快:通过哈希函数快速定位键值对,平均时间复杂度接近O(1)。
    • 空间效率较高:不需要额外的空间存储元素之间的关系,仅需存储键值对本身。
  3. 缺点

    • 不保证元素顺序:插入和访问元素的顺序与实际存储顺序可能不一致,且顺序会随操作动态变化。
    • 线程不安全:在多线程环境下未做同步控制,如需在并发环境中安全使用,应选用ConcurrentHashMap或手动同步。
  4. 适用场景:适用于对插入、删除、查找等操作有较高性能要求,且不关心元素顺序,且仅在单线程或已做外部同步的情况下使用的场景。

TreeMap

TreeMap基于红黑树(Red-Black Tree)实现,提供自动排序功能。特点和适用场景如下:

  1. 实现原理:TreeMap内部使用红黑树存储键值对,键必须实现Comparable接口(或提供Comparator)。红黑树保证了键的有序性,且插入、删除、查找等操作具有对数时间复杂度(O(log n))。

  2. 优点

    • 自动排序:键按自然顺序或自定义比较器顺序排列,可以通过firstKey()lastKey()subMap()等方法方便地进行范围查询。
    • 查询效率稳定:相比HashMap,虽然平均查找时间稍慢,但不受哈希冲突影响,性能更为稳定。
  3. 缺点

    • 查询速度较HashMap慢:由于红黑树的性质,查找、插入、删除等操作的时间复杂度为O(log n),比HashMap的平均O(1)略慢。
    • 线程不安全:与HashMap类似,未做线程同步,不适合在并发环境中直接使用。
  4. 适用场景:适用于需要键按特定顺序排列,且对查找性能要求较高,但不苛求达到哈希表级别的性能,且在单线程或已做外部同步的场景。

LinkedHashMap

LinkedHashMap继承自HashMap,同时实现了java.util.LinkedHashMap接口,结合了HashMap与LinkedList的特点。特点和适用场景如下:

  1. 特点

    • 保持插入/访问顺序:默认情况下,LinkedHashMap维护键值对的插入顺序;通过构造函数指定accessOrder=true,可改为维护最近访问顺序(LRU缓存)。
    • 内部使用双向链表:除了哈希表结构外,每个键值对还链接在一个双向链表中,用于维护元素的顺序。
  2. 优缺点

    • 保留插入/访问顺序:便于按照插入或访问顺序遍历元素,且顺序不受后续操作影响。
    • 线程不安全:与HashMap和TreeMap一样,未提供线程同步。
  3. 适用场景:适用于需要保持元素插入或访问顺序,且在单线程或已做外部同步的场景,如缓存、历史记录等。

Hashtable与ConcurrentHashMap

Hashtable是早期JDK提供的线程安全Map实现,与HashMap类似,但进行了同步处理。特点和适用场景如下:

  1. 特点
    • 线程安全:所有操作都经过同步,避免了多线程环境下的数据不一致问题。
    • 不推荐使用:由于同步粒度过粗(整个Map加锁),在高并发场景下性能较低,且不支持null键和null值。

ConcurrentHashMap是JDK 1.5引入的并发友好的Map实现,提供了细粒度的锁机制,提高了并发性能。特点和适用场景如下:

  1. 特点
    • 线程安全且高效:使用分段锁(Segment Lock)实现细粒度的并发控制,多个修改操作可以并行进行,性能优于同步的HashMap和Hashtable。
    • 支持null键和null值:与HashMap类似,允许插入null键和null值。

综上,Java中的Map接口及其常见实现类各有特点,选择时应根据实际需求(如是否需要排序、是否需要线程安全、是否在意插入/访问顺序等)和性能要求来决定使用哪一种。在并发环境中,优先考虑使用ConcurrentHashMap。

标签:Map,顺序,Java,HashMap,插入,Set,键值,线程
From: https://blog.csdn.net/m0_61635718/article/details/137347085

相关文章

  • Java集合框架详解:List、Set、Map及其实现类的使用与特性 第四章
    目录一、Java集合框架的选择与优化选择策略性能优化二、结论一、Java集合框架的选择与优化选择策略根据数据特性和应用需求,选择合适的Java集合类型应考虑以下几个关键因素:是否允许重复:不允许重复:如果元素必须唯一,应选择Set接口的实现类,如HashSet(无序,查找速度快)或T......
  • 走向Java的第一步,Hello,World
    此笔记仅针对自己在学习路上所学所遇的问题!!!不管任何语言,敲的第一个代码毋庸置疑就是helloworld,Java的helloworld如下:点击查看代码publicclassHello{ publicstatic void main(String[]args){ System.out.print("Hello,World!!"); }}此处注意点:Java书写需严格规......
  • 用JavaScript实现响应式设计的魔法
    在数字世界的迷宫中,响应式设计就像是一把万能钥匙,能打开任何大小屏幕的大门。不论是巨大的桌面显示器,还是袖珍的手机屏幕,响应式设计确保你的网站或应用能在任何设备上都提供优质的用户体验。但如何用JavaScript施展这种魔法呢?让我们一探究竟。使用媒体查询监听器在CSS中,我......
  • 使用JavaScript提升Web应用的安全性
    在构建Web应用时,安全性是一个我们绝不能忽视的重要方面。随着网络攻击手段的日益狡猾和复杂,如何保护我们的应用和用户的数据安全成了每个开发者必须面对的问题。本文将介绍一些常见的Web安全威胁,比如跨站脚本攻击(XSS)、跨站请求伪造(CSRF),以及如何通过使用ContentSecurityPol......
  • Java基础知识
    1.Java中的几种数据类型除了8种简单数据类型之外的所有数据类型都被称为引用数据类型,引用数据类型变量的内存大小统一为4字节,记录的是其引用对象的地址。2.全局变量与局部变量实例变量、类变量、常量都是属于成员变量的,成员变量又被称为全局变量。被static关键字修饰的变量,叫......
  • 逆袭大厂之路——Java程序员必备金九银十跳槽面试涨薪秘籍
    JAVA集合JAVA多线程并发JAVA基础Spring原理微服务Netty与RPC网络ZookeeperKafka自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是......
  • 使用inno setup 打包Pyinstaller生成的文件夹
    背景:pyinstaller6.5.0、InnoSetup6.2.21. 需要先使用pyinstaller打包,生成包括exe在内的可执行文件夹注意:直接使用pyinstaller打包,生成的文件夹较大,建议在python安装路径中的Scripts文件夹中,将脚本等文件复制过来,将打包命令中的pyinstaller替换为pyinstaller.exe打包,生成的文......
  • Java 对象和类
    在理解Java的类和对象之前,先简单介绍一下面向对象的程序设计。程序设计是通过对象对程序进行设计,对象代表一个实体,实体可以清楚地被识别。Java作为一种面向对象语言。支持以下基本概念:多态继承封装抽象类对象实例方法消息解析本节我们重点研究对象和类的概念。对象:对象是类......
  • Java 基本数据类型
    变量就是申请内存来存储值。也就是说,当创建变量的时候,需要在内存中申请空间。内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据。因此,通过定义不同类型的变量,可以在内存中储存整数、小数或者字符。Java的两大数据类型:内置数据类型引用数据类......
  • Java 修饰符
    Java语言提供了很多修饰符,主要分为以下两类:访问修饰符非访问修饰符修饰符用来定义类、方法或者变量,通常放在语句的最前端。我们通过下面的例子来说明:publicclassclassName{//...}privatebooleanmyFlag;staticfinaldoubleweeks=9.5;protectedstaticfin......