在上一篇,我已经稍微详细的介绍了。什么是java含义里的集合。这个基础这些就不说了
1.map类来自哪个jar包
2.有了单列以后,为什么还要使用双列。
3.map提供了哪些常用的集合供使用,他们的特点是什么。如何在不同场景下,选择使用。
3.在代码层面使用不同类型的map需要掌握哪些代码量。
1.map类来自哪个jar包
这是一个很好的追问,它触及了Java的核心模块化设计。
核心答案:Map接口不依赖任何外部Jar包。
更准确的解释是:
来源:Map是 Java标准库 (Java Standard Library) 的核心部分。
位置:它的字节码被打包在 rt.jar (Java 8及之前) 或 java.base模块 (Java 9及之后的模块化系统) 中。
如何获得:只要你安装了JDK (Java Development Kit),这个库就随之存在。因此,你无需像使用Spring、MyBatis等第三方库那样在 pom.xml 或 build.gradle 中添加任何依赖。
简单类比:Map就像你电脑操作系统自带的"记事本"程序,一装好系统就有,不需要额外下载安装。它属于Java语言和平台的基础设施。
2.有了单列以后,为什么还要使用双列。
简介:我们在日常场景下,集合装的最多的是类和对象。你看,如果把数据放在list里面,要找其中一个对象里面的属性,就要一个一个遍历,map至少提供了一个k,也就是名字,找到数据也快,所以这个实际上好的作用是,
1.查的快。在java这个数据领域,内存里的数据,查的快。
2.由于java里的数据,要和其他机器里的数据类型打交道,有的数据类型,比方说redis,kv里面的,就更好的匹配一点。
3.第三点:内置去重与唯一性约束
Map的键(Key)天然具备唯一性,这比用Set或手动去重更直接、更强大。
4.第四点:实现多级索引与复杂关系映射
Map可以轻松嵌套,形成多级查找结构,这是Collection难以清晰表达的。
第三个问题:
HashMap是你的默认首选。在99%不涉及并发和特殊排序的需求下,它因其最优的平均时间复杂度(O(1)) 而成为性能最好的通用选择。
接下来,当你遇到以下具体场景时,就需要考虑其他实现了:
考量维度 如果你需要... 那么选择 原因与示例
- 线程安全 在多线程环境下共享同一个Map ConcurrentHashMap HashMap线程不安全,并发写会导致数据错乱或死循环。Hashtable(锁整个表)性能差,而ConcurrentHashMap(JDK8+采用分段锁/CAS)在保证安全的同时性能最优。
- 键的顺序 让所有的键按照某种规则自动排序 TreeMap HashMap键是无序的。TreeMap基于红黑树实现,可以按键的自然顺序(如字符串字典序、数字大小)或自定义比较器排序。例如,需要按员工ID排序并快速找到某个范围内的ID。
- 遍历顺序 保持元素的插入顺序,或实现最近最少使用(LRU)缓存 LinkedHashMap LinkedHashMap在HashMap基础上增加了一个双向链表来维护顺序。插入顺序模式适合需要"按添加的先后顺序处理"的场景;访问顺序模式(accessOrder=true)是构建LRU缓存的基石。
第四个问题:
hashmap篇要掌握的代码量
1.创建数据容器
2.对容器里的数据进行curd
3.取出来容器里的数据。
我们先看一个简单的demo
java
import java.util.HashMap;
import java.util.Map;
public class HashMapBasic {
public static void main(String[] args) {
// 1. 创建HashMap:就像买个新笔记本
Map<String, Integer> scoreMap = new HashMap<>();
// 2. 核心操作:增、删、改、查
// 增/改:put(key, value) - 记录同学分数
scoreMap.put("张三", 90);
scoreMap.put("李四", 85);
scoreMap.put("王五", 95);
scoreMap.put("张三", 100); // "改":键已存在,会覆盖旧值(90->100)
// 查:get(key) - 查询李四的分数
Integer liSiScore = scoreMap.get("李四");
System.out.println("李四的分数是:" + liSiScore); // 输出:85
// 查不存在的键:返回null
Integer unknownScore = scoreMap.get("赵六");
System.out.println("赵六的分数是:" + unknownScore); // 输出:null
// 删:remove(key) - 删除王五的记录
Integer removedScore = scoreMap.remove("王五");
System.out.println("删除的王五分数是:" + removedScore); // 输出:95
// 3. 遍历:两种最常用方法
System.out.println("\n=== 遍历所有同学成绩 ===");
// 方法一:遍历键值对(推荐)
for (Map.Entry<String, Integer> entry : scoreMap.entrySet()) {
System.out.println(entry.getKey() + " => " + entry.getValue());
}
// 方法二:先遍历键,再通过键取值
for (String name : scoreMap.keySet()) {
System.out.println(name + " -> " + scoreMap.get(name));
}
}
}
这个其实很弱:只是一些基础的概念
但是实际上,我们在代码里常用的是。
1.v的值是obj类型
2.赋值常用的是一个调用方法的返回值来接收
3.常见的情况是,要遍历,拿到hashmap这个容器里的数据,或者过滤,用一个新的容器接收。
对于使用hashmap:
k命名的最佳实践