当前位置: 首页 > news >正文

Java集合-Map讲解

目录

  • 一、集合框架层次结构
  • 二、Collection集合
    • 2、Map集合
      • 1. HashMap - 最常用的Map
      • 2. LinkedHashMap - 保持插入顺序的Map
      • 3. TreeMap - 按键排序的Map
      • 4.ConcurrentHashMap - 高并发Map
      • 5.Collections.synchronizedMap
      • 6.性能对比表

Java 集合框架(Collections Framework)是 Java 中用于存储和操作数据组的重要架构。它提供了一组接口、实现类和算法。

一、集合框架层次结构

Collection (接口) ├── List (接口 - 有序,可重复) │ ├── ArrayList (实现类) │ ├── LinkedList (实现类) │ ├── Vector (线程安全,已过时) │ └── Stack (继承Vector) │ ├── Set (接口 - 无序,不可重复) │ ├── HashSet (实现类) │ │ └── LinkedHashSet (保持插入顺序) │ ├── SortedSet (接口) │ │ └── TreeSet (实现类) │ └── EnumSet (专用于枚举) │ └── Queue (接口 - 队列) ├── Deque (双端队列接口) │ ├── ArrayDeque (实现类) │ └── LinkedList (也实现了Deque) │ ├── PriorityQueue (优先队列) └── BlockingQueue (阻塞队列接口) ├── ArrayBlockingQueue ├── LinkedBlockingQueue └── PriorityBlockingQueue Map (接口 - 键值对) ├── HashMap (实现类) │ └── LinkedHashMap (保持插入顺序) ├── TreeMap (基于红黑树) ├── Hashtable (线程安全,已过时) ├── WeakHashMap (弱引用) └── ConcurrentHashMap (并发版)

Java集合大致可以分为两大体系,一个是Collection,另一个是Map

  • Collection:主要由ListSetQueue接口组成,List代表有序、重复的集合;其中Set代表无序、不可重复的集合;Queue体系集合,代表一种队列集合实现。
  • Map:则代表具有映射关系的键值对集合。
    java.util.Collection下的接口和继承类关系简易结构图:

    java.util.Map下的接口和继承类关系简易结构图:


其中,Java 集合框架中主要封装的是典型的数据结构和算法,如动态数组、双向链表、队列、栈、Set、Map等。

二、Collection集合

通过集合的关系图我们可以知道Collection是集合的顶层父类,他定义了集合的基本方法如

基本操作方法

方法签名功能描述返回值示例时间复杂度
int size()返回集合中元素的数量元素个数list.size()3O(1)
boolean isEmpty()判断集合是否为空true/falselist.isEmpty()falseO(1)
boolean contains(Object o)判断是否包含指定元素true/falselist.contains("A")trueList: O(n)
Set: O(1)
TreeSet: O(log n)
boolean add(E e)添加元素到集合是否成功list.add("D")trueArrayList: 均摊O(1)
LinkedList: O(1)
TreeSet: O(log n)
boolean remove(Object o)移除指定元素是否成功list.remove("A")trueArrayList: O(n)
LinkedList: O(n)
HashSet: O(1)

批量操作方法

方法签名功能描述返回值示例说明
boolean containsAll(Collection<?> c)是否包含集合c中所有元素true/falselist.containsAll(subList)检查子集关系
boolean addAll(Collection<? extends E> c)添加集合c中所有元素是否改变list.addAll(anotherList)批量添加
boolean removeAll(Collection<?> c)移除集合c中所有元素是否改变list.removeAll(toRemove)差集操作
boolean retainAll(Collection<?> c)仅保留集合c中元素是否改变list.retainAll(common)交集操作
void clear()清空集合所有元素list.clear()集合变为空

转换和迭代方法

方法签名功能描述返回值示例说明
Object[] toArray()转换为Object数组Object数组list.toArray()返回新数组
<T> T[] toArray(T[] a)转换为指定类型数组指定类型数组list.toArray(new String[0])类型安全转换
Iterator<E> iterator()返回迭代器Iterator对象list.iterator()用于遍历集合
default boolean removeIf(Predicate<? super E> filter)条件删除是否改变list.removeIf(s -> s.length() > 3)Java 8+
default Spliterator<E> spliterator()返回分割迭代器Spliterator对象list.spliterator()Java 8+,并行遍历
default Stream<E> stream()返回顺序流Stream对象list.stream()Java 8+,流操作
default Stream<E> parallelStream()返回并行流Stream对象list.parallelStream()Java 8+,并行流操作

集合运算方法

方法数学运算示意图示例
addAll()并集A ∪ BA.addAll(B)
retainAll()交集A ∩ BA.retainAll(B)
removeAll()差集A - BA.removeAll(B)

常见操作示例

操作需求代码示例说明
遍历集合for (E e : collection) { ... }增强for循环
安全遍历并删除iterator.remove()使用迭代器删除
转换为数组String[] arr = coll.toArray(new String[0])推荐写法
批量添加元素coll.addAll(Arrays.asList("A","B","C"))初始化集合
过滤集合coll.removeIf(e -> e.startsWith("A"))Java 8+
集合判空if (!coll.isEmpty()) { ... }优于size() > 0

注意事项表格

方法注意事项推荐做法
contains()依赖equals()hashCode()正确实现这两个方法
remove(Object)只删除第一个匹配项使用removeIf()删除所有
toArray()无参方法返回Object[]使用带参方法指定类型
addAll()可能修改原集合注意并发修改异常
clear()不释放元素引用大集合考虑设为null
iterator()遍历时不能修改集合使用迭代器的remove()
场景建议理由
频繁包含检查使用HashSetO(1)时间复杂度
频繁插入删除使用LinkedList首尾操作O(1)
随机访问使用ArrayListO(1)索引访问
需要排序使用TreeSet自动维护顺序
线程安全使用并发集合ConcurrentHashMap
只读操作使用不可变集合Collections.unmodifiableXXX()

Collection集合中所包含的方法:

publicinterfaceCollection<E>extendsIterable<E>{// 基本操作方法intsize();booleanisEmpty();booleancontains(Objecto);booleanadd(Ee);booleanremove(Objecto);// 批量操作booleancontainsAll(Collection<?>c);booleanaddAll(Collection<?extendsE>c);booleanremoveAll(Collection<?>c);booleanretainAll(Collection<?>c);voidclear();// 数组转换Object[]toArray();<T>T[]toArray(T[]a);// 迭代器Iterator<E>iterator();// Java 8 新增方法defaultbooleanremoveIf(Predicate<?superE>filter){...}defaultSpliterator<E>spliterator(){...}defaultStream<E>stream(){...}defaultStream<E>parallelStream(){...}}

2、Map集合

Map映射是将键映射到值的对象。映射不能包含重复的键,每个键最多可以映射到一个值。

Map 接口层次结构

Map<K,V> (接口) ├── HashMap<K,V> (最常用) │ └── LinkedHashMap<K,V> (保持插入顺序) ├── TreeMap<K,V> (按键排序) ├── Hashtable<K,V> (已过时,线程安全) ├── ConcurrentHashMap<K,V> (并发HashMap) ├── EnumMap<K,V> (专为枚举设计) └── WeakHashMap<K,V> (弱引用Map)

1. HashMap - 最常用的Map

基本使用

// 创建HashMapMap<String,Integer>studentScores=newHashMap<>();// 添加键值对studentScores.put("张三",85);studentScores.put("李四",92);studentScores.put("王五",78);studentScores.put("张三",90);// 覆盖之前的85// 获取值Integerscore=studentScores.get("李四");// 92Integerunknown=studentScores.get("赵六");// null// 判断包含booleanhasZhang=studentScores.containsKey("张三");// truebooleanhasScore100=studentScores.containsValue(100);// false// 遍历for(Map.Entry<String,Integer>entry:studentScores.entrySet()){System.out.println(entry.getKey()+": "+entry.getValue());}// Java 8+ 遍历studentScores.forEach((name,score)->{System.out.println(name+" => "+score);});

高级操作

Map<String,Integer>map=newHashMap<>();// 1. 如果不存在则添加map.putIfAbsent("张三",85);// 添加map.putIfAbsent("张三",90);// 不添加,因为已存在// 2. 计算新值map.compute("张三",(key,oldValue)->oldValue==null?100:oldValue+10);// 95// 3. 如果不存在则计算map.computeIfAbsent("李四",key->80);// 添加李四:80// 4. 如果存在则计算map.computeIfPresent("李四",(key,value)->value+5);// 李四:85// 5. 合并map.merge("张三",10,Integer::sum);// 张三:105 (95+10)

2. LinkedHashMap - 保持插入顺序的Map

// 创建LinkedHashMapMap<String,String>accessOrder=newLinkedHashMap<>();// 添加数据(保持插入顺序)accessOrder.put("首页","/home");accessOrder.put("产品","/products");accessOrder.put("关于","/about");accessOrder.put("联系","/contact");System.out.println("插入顺序:");accessOrder.forEach((k,v)->System.out.println(k+" -> "+v));// 输出顺序:首页 → 产品 → 关于 → 联系// 实现LRU缓存(最近最少使用)Map<String,String>lruCache=newLinkedHashMap<>(16,0.75f,true){@OverrideprotectedbooleanremoveEldestEntry(Map.Entryeldest){returnsize()>3;// 最多缓存3个}};lruCache.put("A","数据A");lruCache.put("B","数据B");lruCache.put("C","数据C");lruCache.get("A");// 访问A,A变成最近使用lruCache.put("D","数据D");// B被移除(最久未使用)System.out.println("LRU缓存:"+lruCache.keySet());// [C, A, D]

3. TreeMap - 按键排序的Map

// 创建TreeMap(默认按键的自然顺序)TreeMap<String,Integer>sortedMap=newTreeMap<>();sortedMap.put("orange",5);sortedMap.put("apple",3);sortedMap.put("banana",2);sortedMap.put("grape",4);System.out.println("按键排序:");sortedMap.forEach((k,v)->System.out.println(k+": "+v));// apple:3 → banana:2 → grape:4 → orange:5// 范围查询StringfirstKey=sortedMap.firstKey();// "apple"StringlastKey=sortedMap.lastKey();// "orange"// 子映射SortedMap<String,Integer>headMap=sortedMap.headMap("grape");// apple:3, banana:2SortedMap<String,Integer>tailMap=sortedMap.tailMap("banana");// banana:2, grape:4, orange:5// 导航方法Stringlower=sortedMap.lowerKey("grape");// "banana"(小于)Stringfloor=sortedMap.floorKey("grape");// "grape"(小于等于)Stringhigher=sortedMap.higherKey("grape");// "orange"(大于)Stringceiling=sortedMap.ceilingKey("grape");// "grape"(大于等于)

4.ConcurrentHashMap - 高并发Map

// 创建ConcurrentHashMapConcurrentHashMap<String,Integer>concurrentMap=newConcurrentHashMap<>();// 线程安全的操作concurrentMap.put("A",1);concurrentMap.putIfAbsent("A",2);// 不会覆盖// 原子操作concurrentMap.compute("A",(k,v)->v==null?1:v+1);// 批量操作(线程安全)concurrentMap.forEach(2,(k,v)->System.out.println(k+": "+v));// 搜索Integerresult=concurrentMap.search(2,(k,v)->v>5?v:null);// 归约intsum=concurrentMap.reduceValues(2,Integer::sum);

5.Collections.synchronizedMap

// 包装普通Map为线程安全Map<String,Integer>syncMap=Collections.synchronizedMap(newHashMap<>());// 使用时要手动同步synchronized(syncMap){for(Map.Entry<String,Integer>entry:syncMap.entrySet()){// 操作}}

6.性能对比表

操作HashMapLinkedHashMapTreeMapConcurrentHashMap
get()O(1)O(1)O(log n)O(1)
put()O(1)O(1)O(log n)O(1)
containsKey()O(1)O(1)O(log n)O(1)
遍历无序插入顺序按键排序无序
线程安全
http://www.cnnetsun.cn/news/87869.html

相关文章:

  • Docker 从入门到精通教程
  • waitGroup底层源码分析
  • LobeChat能否用于编写Prometheus告警规则?可观测性增强
  • 大模型学习全攻略:七阶段系统学习路线图,从基础到实战应用,非常详细收藏我这一篇就够了
  • 玄晶引擎AI数字员工更新深度测评:Sora2赋能+RPA运营,AI内容生产进入效率革命期
  • YOLOv5中使用torch加载自定义模型进行目标检测
  • LobeChat能否隐藏源码信息?增强系统隐蔽性
  • React 的桶算法详解
  • 深入理解Dify的依赖管理机制(Dependency Walker适用场景)
  • CordovaOpenHarmony车辆管理系统开发
  • YOLO训练中断恢复技巧:避免重复计算
  • 电气自动化专业相关认证解析
  • 手机内存告急?MAZANOKE 压缩照片不损画质,加载cpolar远程用更方便
  • 「直通」英伟达,蓝思科技补齐AI算力布局又一块拼图
  • Dify + Jenkins 实现AI应用持续集成与自动化部署
  • MTS AI智能聚合公链正式上线
  • LobeChat能否生成SQL语句?数据库查询助手上线
  • 告别深夜批改:用Qwen3-VL大模型打造会“理解”的作文阅卷助手
  • LobeChat语音输入功能实测:让AI对话更自然流畅
  • 基于PaddlePaddle的视觉模型训练实战:从Docker安装到GPU算力调用
  • LobeChat能否实现多轮对话优化?上下文理解增强策略
  • 如何在Windows和Linux上完成TensorRT安装包的部署
  • Dify在边缘计算场景下部署的可行性评估
  • LobeChat能否对接Airtable?轻量级数据库联动方案
  • LobeChat能否实现AI故事续写?创意写作激发灵感
  • AI知识科普丨什么是 ModelOps?
  • Windows 10下Anaconda安装OpenCV指南
  • LangChain与AutoGPT核心差异与应用场景解析
  • 文件上传靶场的3种白名单,3种黑名单,以及3种针对文件内容的修改。特性靶场、get,post传参方式区别(抓包看看),正则匹配,以及高亮函数作用
  • ENSP下载官网打不开?这份备用清单请收好