双列集合 Map

本文详细介绍了Java中的Map集合,包括其特点、常用方法(如键找值、键值对和Lambda遍历),以及HashMap、LinkedHashMap和TreeMap的具体实现、排序规则和注意事项。

双列集合  Map

每次存取都是一对儿元素

一、Map集合概述

1.1 Map集合即双列集合,集合中的每一个元素都是以key=value的形式成对儿出现的,一个key=value就是一个键值对。Java中用Entry类的对象来表示键值对对象

1.2 特点:键不能重复,值可以重复,每个键只能找到自己的对应的值

1.3 注意:Map系列的集合特点都是由键决定的,值只是一个附属品,值是不做要求的

1.4 Map集合体系

  • 1.4.1 HashMap(由键决定特点):无序、不重复、无索引
  • 1.4.2 LinkedHashMap(由键决定特点):有序、不重复、无索引
  • 1.4.3 TreeMap(由键决定特点):按照大小默认升序排序、不重复、无索引

二、常用方法

 

三、遍历方式

3.1 键找值

  • 先获取Map集合全部的键,再通过遍历键找值

 

 

3.2 键值对

  • 直接获取每一个Entry对象,把Entry存储到集合中去,再通过Entry对象获取键和值

 

3.3 Lambda

  • 需要使用forEach方法,最好结合Lambda表达式使用

四、HashMap

4.1 特点

  • 无序、不重复、无索引

4.2 HashSet底层就是HashMap

  • 创建HashSet集合时,底层帮你创建了HashMap集合;往HashSet集合中添加元素时,底层调用了Map集合的put方法把元素作为了键来存储,所以HashSet集合就是把HashMap集合的值忽略不看。

4.3 底层数据结构---哈希表结构

  • 是一种增删改查性能都比较好的数据结构
  • JDK8之前:哈希表=数组+链表
  • JDK8之后:哈希表 =数组+链表+红黑树

4.4 底层存储步骤

  • 1、第一次往HashMap集合中存储键值对时,底层会创建一个长度为16的数组
  • 2、把键和值封装成一个对象,叫做Entry对象
  • 3、根据Entry对象的键计算hashCode值(和值无关)
  • 4、用哈希值和数组长度做求余算法,得到一个索引位置
  • 5、判断这个索引的位置是否为null,如果为null,就直接将这个Entry对象存入这个索引位置;如果不为null,则进行下一步
  • 6、使用equals方法判断两个对象的键是否相同,如果不同(false)则以链表的形式往下挂(JDK8开始 尾插法);如果相同(true),则认为键重复,此时新的键值对会替换旧的键值对

4.5 底层存储注意事项

  • 1、底层数组默认长度为16,如果数组中有超过12位置已经存储了元素,则会对数组进行扩容2倍,数组扩容的加载因子为0.75,即阈值:16*0.75=12.
  • 2、数组的同一个索引位置有多个元素、并且在8个元素以内(包括8)则以链表的形式存储

• JDK8以前:链表采用头插法

• JDK8以后:链表采用尾插法

  • 3、数组的同一个索引位置有多个元素,并且超过了8个即链表长度超过8并且数组长度>=64,则转换成红黑树的形式

4.6 键的不可重复

  • 往Map集合存储自定义对象作为键时,为了保证键的唯一性,应重写hashCode方法和equals方法

五、LinkedHashMap

5.·1 特点:有序、不重复、无索引

5.2 底层原理

  • 底层多一个双向链表来维护键的存储顺序,取元素时,先取头节点元素,然后再依次取下一个节点,一直到尾节点,所以是有序的。

六、TreeMap

6.1 特点:默认按照键的升序排序、键不重复、无索引

6.2 底层原理

  • 底层由红黑树实现,所以可以对键进行排序

6.3 排序规则

  • 1、写个实现类来实现接口Comparable接口,重写compareTo方法
  • 2、创建TreeMap集合时,直接传递Comparator比较器对象

6.4 注意:只有TreeMap的键才能排序,HashMap的键不能排序

七、集合嵌套示例

 

### 关于双列集合的数据结构、使用方法及其实现原理 #### 数据结构概述 双列集合是一种基于键值对(key-value pair)存储数据的集合类型。它在 Java 中主要由 `Map` 接口及其具体实现类构成,例如 `HashMap`、`TreeMap` 和 `LinkedHashMap` 等[^1]。这些实现类提供了不同的功能和性能特点。 - **键值对存储**:双列集合的核心特点是通过键来定位其对应的值。每个键只能映射到一个值,而多个键可以共享同一个值[^2]。 - **无序性与有序性**:大多数双列集合(如 `HashMap`)不保证元素的迭代顺序。然而,某些实现类(如 `TreeMap` 和 `LinkedHashMap`)则提供特定的排序或插入顺序保障[^3]。 --- #### 使用方法详解 以下是双列集合的主要操作方式: 1. **创建实例** 创建一个双列集合可以通过指定具体的实现类完成。例如: ```java Map<String, Integer> map = new HashMap<>(); ``` 2. **添加键值对** 使用 `put()` 方法将键值对插入集合中。如果键已存在,则会覆盖原有的值。 ```java map.put("Alice", 25); map.put("Bob", 30); ``` 3. **获取值** 利用 `get()` 方法通过键检索对应的值。如果键不存在,则返回 `null`。 ```java int ageOfAlice = map.get("Alice"); // 返回 25 ``` 4. **删除键值对** 调用 `remove()` 方法移除指定键的条目。 ```java map.remove("Bob"); ``` 5. **判断是否存在某个键或值** - 检查键的存在性:`containsKey()` - 检查值的存在性:`containsValue()` ```java boolean hasAlice = map.containsKey("Alice"); // true boolean hasAge30 = map.containsValue(30); // false ``` 6. **遍历集合** 遍历双列集合有多种方式,常见的包括: - 遍历键集 (`keySet`): ```java for (String key : map.keySet()) { System.out.println(key + ": " + map.get(key)); } ``` - 遍历条目集 (`entrySet`): ```java for (Map.Entry<String, Integer> entry : map.entrySet()) { System.out.println(entry.getKey() + ": " + entry.getValue()); } ``` 7. **清空集合** 使用 `clear()` 方法清除所有键值对。 ```java map.clear(); ``` --- #### 实现原理分析 1. **哈希表机制(以 `HashMap` 为例)** - `HashMap` 基于哈希表实现,内部维护了一个数组用于存储桶(bucket),每个桶可能是一个链表或红黑树[^4]。 - 当调用 `put()` 插入键值对时,计算键的哈希码并将其映射到相应的桶位置。如果发生冲突(两个键具有相同的哈希码),则通过链地址法解决冲突。 - 如果链表长度超过阈值(默认为8),该链表会被转换为红黑树以提高查询效率。 2. **平衡二叉树(以 `TreeMap` 为例)** - `TreeMap` 基于红黑树实现,能够保持按键的自然顺序或自定义比较器规定的顺序排列。 - 所有的插入、删除和查找操作的时间复杂度均为 O(log n),因为每次调整都会重新平衡树结构。 3. **链接列表(以 `LinkedHashMap` 为例)** - `LinkedHashMap` 继承自 `HashMap` 并额外维护了一条双向链表,记录了键值对的插入顺序。 - 这种设计使其既具备高效访问能力又保留了迭代顺序。 --- #### 总结 双列集合Java 编程中非常重要的工具之一,适用于需要快速按键查找值的场景。理解其基本特性和底层实现有助于开发者更合理地选择合适的实现类,并优化程序性能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值