java-collections-map——面题
Map
Map常用子类
- HashMap:HashMap 是最常用的 Map 实现之一,它基于哈希表实现,提供了 O(1) 时间复杂度的插入、删除和查找操作。
- Hashtable:Hashtable 是较早期的 Java 集合类,它是线程安全的,但性能通常比 HashMap 差,因为它的方法是同步的。
- TreeMap:TreeMap 是基于红黑树实现的有序 Map,它根据键的自然顺序或自定义顺序进行排序。TreeMap 提供了一些附加的方法来处理有序映射。
- LinkedHashMap:LinkedHashMap 继承自 HashMap,它使用双向链表维护插入顺序或者访问顺序,因此迭代顺序可以预测。
- ConcurrentHashMap:ConcurrentHashMap是Hashtable替代,相比性能较好,线程安全,无序。
- ConcurrentSkipListMap:线程安全,有序。
扩展:还有其他子类比如ConcurrentHashMap、WeakHashMap、IdentityHashMap、EnumMap...
EnumMap 是针对枚举类型的特定实现,它的键必须是枚举类型的值。
HashMap
/**
* hashMap_demo
* HashMap:非线程安全的 Map 实现
* 数据结构:数组 + 链表 + (1.8加的红黑树)
* 遍历顺序:无序
* 是否线程安全:线程不安全
* 扩容机制: 当HashMap容量大小(默认16)达到容量的加载因子的大小(默认0.75)自动扩容两倍
* 最大容量:2^30 - 1 (即 1,073,741,823)
* null值操作:允许使用一个 null 键,多个 null 值
*/
@Test
public void hashMap_demo() {
HashMap<String,String> hashMap = new HashMap<>(16, 0.75f);
for (int i = 1; i <= 3; i++) {
hashMap.put("test"+i,"test");
}
hashMap.put(null,"test");
for (Map.Entry<String, String> entry : hashMap.entrySet()) {
System.out.print(" Key: " + entry.getKey());
}
}
执行打印
Key: null Key: test2 Key: test3 Key: test1
Hashtable
/**
* hashtable_demo
* Hashtable:线程安全无序的 Map 实现
* 实现方式:数组 + 链表
* 遍历顺序:无序
* 是否线程安全:线程安全,所有公共方法都是同步的 synchronization 多线程环境中,当一个线程正在修改 Hashtable 时,其他线程进入等待。
* 扩容机制: 当HashMap容量大小(默认11)达到容量的加载因子的大小(默认0.75)自动扩容两倍
* null值操作:不允许使用 null 键或 null 值
*/
@Test
public void hashtable_demo() {
Hashtable<String,String> hashtable = new Hashtable<>(11, 0.75f);
for (int i = 1; i <= 3; i++) {
hashtable.put("test"+i,"test");
}
//hashtable.put(null,"test");//键设置为null 抛出java.lang.NullPointerException
for (Map.Entry<String, String> entry : hashtable.entrySet()) {
System.out.print(" Key: " + entry.getKey());
}
}
执行打印
Key: test2 Key: test3 Key: test1
TreeMap
/**
* treeMap_demo
* TreeMap 线程安全有序 Map 实现
* 实现方式:基于红黑树数据结构
* 遍历顺序:默认键顺序按照自然顺序来排序,也可以重写compare方法自定义排序逻辑
* 是否线程安全:线程安全
* 扩容机制: 基于红黑树,没有扩容机制
*/
@Test
public void treeMap_demo() {
//TreeMap<String,String> treeMap = new TreeMap<>();//默认键顺序按照自然顺序来排序
TreeMap<String,String> treeMap = new TreeMap<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
//return o1.compareTo(o2); // 默认自然顺序
return o2.length() - o1.length(); // 使用自定义逻辑 例如,根据字符串长度倒序排序
}
});
treeMap.put("az2","test");
treeMap.put("nam3","test");
treeMap.put("mapf4","test");
for (Map.Entry<String, String> entry : treeMap.entrySet()) {
System.out.print(" Key: " + entry.getKey());
}
}
执行打印
Key: mapf4 Key: nam3 Key: az2
LinkedHashMap
/**
* linkedHashMap_demo
* LinkedHashMap:非线程安全无序 Map 实现,继承 HashMap
* 实现方式:哈希表 + 双向链表
* 是否线程安全:线程不安全
* 遍历顺序:当元素添加时位置到链表末尾,遍历时,按照插入的顺序返回
* 设置访问顺序参数策略: 默认是false,设置为true的是如果有get或put操作,将被操作的元素追加到链表的末尾,顺序排后
* 扩容机制:与 HashMap 相同
*/
@Test
public void linkedHashMap_demo(){
//设置顺序方式 默认是false
LinkedHashMap<String,String> linkedHashMap = new LinkedHashMap<>(16, 0.75f, false);
//LinkedHashMap<String,String> linkedHashMap = new LinkedHashMap<>(16, 0.75f, true);
for (int i = 1; i <= 3; i++) {
linkedHashMap.put("test"+i,"test");
}
// 默认按照插入顺序,遍历所有的键和值
for (Map.Entry<String, String> entry : linkedHashMap.entrySet()) {
System.out.print(" Key: " + entry.getKey());
}
System.out.println("\n --------------");
linkedHashMap.put("test0","test");
linkedHashMap.get("test1");
for (Map.Entry<String, String> entry : linkedHashMap.entrySet()) {
System.out.print(" Key: " + entry.getKey());
}
}
执行打印
1.设置为false的结果:
Key: test1 Key: test2 Key: test3
//--------------
Key: test1 Key: test2 Key: test3 Key: test0
2.设置为true的结果:
Key: test1 Key: test2 Key: test3
//--------------
Key: test2 Key: test3 Key: test0 Key: test1
ConcurrentHashMap
/**
* concurrentHashMap_demo
* ConcurrentHashMap:线程安全无序 Map 实现
* 实现方式:数组 + 链表 + 红黑树
* 是否线程安全:线程安全 1.8开始使用 CAS 操作和循环来保证对数据的修改是线程安全的,之前使用分段锁。
* 遍历顺序:无序
* 扩容机制:与 HashMap 相同
*/
@Test
public void concurrentHashMap_demo(){
ConcurrentHashMap<String,String> concurrentHashMap = new ConcurrentHashMap<>(16, 0.75f);
for (int i = 1; i <= 3; i++) {
concurrentHashMap.put("test"+i,"test");
}
for (Map.Entry<String, String> entry : concurrentHashMap.entrySet()) {
System.out.print(" Key: " + entry.getKey());
}
}
执行打印
Key: test2 Key: test3 Key: test1
ConcurrentSkipListMap
/**
* concurrentSkipListMap_demo
* ConcurrentSkipListMap:线程安全有序 Map 实现
* 实现方式:基于跳表(Skip List)数据结构,提供了有序集合的快速查找、插入和删除操作。
* 是否线程安全:线程安全
* 遍历顺序:有序
* 顺序机制:默认键顺序按照自然顺序来排序,也可以重写compare方法自定义排序逻辑
* 扩容机制:ConcurrentSkipListMap 不是一个动态扩容的数据结构,而是由用户根据需要手动进行扩容的。
*/
@Test
public void concurrentSkipListMap_demo() throws InterruptedException {
// ConcurrentSkipListMap<String,String> concurrentSkipListMap = new ConcurrentSkipListMap<>();
ConcurrentSkipListMap<Integer, String> concurrentSkipListMap = new ConcurrentSkipListMap<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
System.out.print("o1:"+o1 +" o2:"+o2+"\n");
// 定义比较逻辑
// return o1.compareTo(o2);
return Integer.compare(o2,o1);//倒序
}
});
for (int i = 1; i <= 3; i++) {
concurrentSkipListMap.put( i,"test");
}
for (Map.Entry<Integer, String> entry : concurrentSkipListMap.entrySet()) {
System.out.print(" Key: " + entry.getKey());
}
}
执行打印
o1:2 o2:1
o1:3 o2:2
Key: 3 Key: 2 Key: 1
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)