news 2026/10/9 5:25:39

01-Java 集合框架全景:从 Collection 到 Map 一张关系网理清

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
01-Java 集合框架全景:从 Collection 到 Map 一张关系网理清

两大根接口一张关系网,复杂度速查表存好

很多人学集合框架,是从List、Map、Set三个单词开始背的,背完还是串不起来:它们之间到底什么关系?为什么HashMap既有"哈希"又有"映射"?Collections和Collection是同一个东西吗?今天我们用一张"关系网"把整个集合框架捋顺,让你之后看任何一篇源码解析都像看地图一样清晰。

一、集合框架为什么要分层?

Java 集合框架(Java Collections Framework,JCF)的设计哲学是:接口定义行为,抽象类提供骨架,具体类给实现。三层各司其职:

  • 接口(Interface):规定"能做什么",比如Collection说"我是一个装元素的容器",List说"我是有序可重复的",Map说"我是键值对"。
  • 抽象类(AbstractXxx):实现接口里大部分通用方法,具体类只需补全差异逻辑,避免重复造轮子。
  • 具体类(Concrete):ArrayList、HashMap、TreeSet等,提供真正的存储结构和算法。

这种设计让你写业务代码时面向接口编程:List<User> list = new ArrayList<>(),哪天想换LinkedList,改一行就行。

二、两大根接口:Collection 与 Map

整个框架有两个互不继承的根,这是初学者最容易迷糊的地方:

Collection(单个元素的容器) ├── List(有序、可重复) │ ├── ArrayList 数组实现,查快改慢 │ ├── LinkedList 双向链表,增删快 │ ├── Vector 线程安全但老旧的数组 │ └── Stack 继承 Vector 的栈(已不推荐) ├── Set(无序、不可重复) │ ├── HashSet 哈希表,最快 │ ├── LinkedHashSet 哈希 + 双向链表,保插入序 │ └── TreeSet 红黑树,按 key 排序 └── Queue / Deque(队列 / 双端队列) ├── ArrayDeque 数组双端队列 ├── PriorityQueue 堆实现的优先队列 └── 各阻塞队列(BlockingQueue 家族) Map(键值对容器,不属于 Collection) ├── HashMap 哈希表,最常用 ├── LinkedHashMap 哈希 + 链表,保插入/访问序 ├── TreeMap 红黑树,按键排序 ├── Hashtable 线程安全但老旧的哈希表 └── ConcurrentHashMap 高并发哈希表

关键点:Map不是Collection的子接口。它的根就是Map<K,V>自己。所以Map没有add(),只有put();它没有继承Collection的任何方法。但Map提供了keySet()、values()、entrySet()三个视图,它们返回的就是Collection/Set,于是两条线在这里交汇。

一个高频面试题:Collection和Collections的区别?前者是接口(根),后者是一个工具类,里面全是静态方法(sort、synchronizedList、emptyList等),用来操作集合。同理Arrays是操作数组的工具类。名字只差一个s,含义天差地别。

三、List / Set / Queue 的行为契约

面试常让你对比三兄弟,记住它们的"契约"就够了:

接口元素顺序重复索引访问典型实现
List有序(插入序)允许支持get(i)ArrayList、LinkedList
Set无序(HashSet)禁止不支持HashSet、TreeSet
Queue按排队规则看实现一般不支持ArrayDeque、PriorityQueue

“有序"在List里指插入顺序可复现、可用下标访问;Set的HashSet不保证顺序,TreeSet按比较器排但也不是"插入序”。这点极易混淆。

四、时间复杂度速查表(背下来)

这是集合框架最实用的"性能地图",建议存下来:

操作ArrayListLinkedListHashMapTreeMapHashSet
按索引查 get(i)O(1)O(n)———
末尾增 addO(1)*O(1)O(1)*O(log n)O(1)*
中间插/删O(n)O(1)**———
查 containO(n)O(n)O(1)*O(log n)O(1)*
取最小/最大O(n)O(n)—O(log n)—

* 均摊复杂度,扩容/哈希冲突时退化为更高
** 已知节点引用时 O(1),若要先遍历定位则是 O(n)

一句话总结性能直觉:随机访问多用 ArrayList,头尾增删多用 ArrayDeque/LinkedList,查重/映射多用 HashMap,要排序用 TreeMap/TreeSet。

五、迭代器:统一的遍历方式

不管底层是数组还是链表,Collection都用同一个Iterator遍历:

List<String>list=newArrayList<>(List.of("a","b","c"));Iterator<String>it=list.iterator();while(it.hasNext()){Strings=it.next();if("b".equals(s))it.remove();// 安全删除}

注意:遍历时用集合自身的remove()会抛ConcurrentModificationException,必须用迭代器的remove(),或用for-each+ 提前收集再删,或用Iterator。这正是后面调优篇要细讲的fail-fast机制。

Map没有Iterator,但entrySet()返回Set<Map.Entry<K,V>>,一样能迭代:

for(Map.Entry<String,Integer>e:map.entrySet()){System.out.println(e.getKey()+"="+e.getValue());}

六、Java 8 之后的函数式增强

集合框架在 Java 8 吃到了大红利:

  • Collection.removeIf(Predicate):一行替代"迭代 + 判断 + 删除"。
  • List.replaceAll(UnaryOperator)、sort(Comparator)。
  • Map.forEach、compute、merge、getOrDefault等,写统计逻辑极爽。
  • StreamAPI 让集合进入"流水线"时代:list.stream().filter(...).map(...).collect(...)。

例子,按城市统计人数:

Map<String,Long>cnt=users.stream().collect(Collectors.groupingBy(User::getCity,Collectors.counting()));

但parallelStream()不是银弹——共享可变状态、线程不安全集合、小数据量都会让它反而不如串行的,调优篇会专门拆。

七、为什么"面向接口编程"这么重要?

回到开头那句List<User> list = new ArrayList<>()。当你把方法参数写成List<T>而不是ArrayList<T>,调用方可以传LinkedList、CopyOnWriteArrayList、Collections.emptyList(),你的方法完全不用改。这是集合框架分层带来的最大红利:解耦"使用方式"和"底层实现"。

同理,返回Map的方法,内部想换成ConcurrentHashMap提升并发,对外签名不变。写 SDK、写业务分层时,这个习惯能少写无数适配代码。

总结

集合框架 = 两大根(Collection / Map)+ 三层结构(接口 / 抽象类 / 实现)+ 一套统一迭代器。记住"List 有序可重复、Set 不可重复、Map 是键值对且不属于 Collection",再配合复杂度速查表,你就拿到了整个框架的地图。后续源码篇都是在给这张地图填充细节。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/9 5:22:50

Spring Boot商场多功能折扣系统:从业务到答辩的毕设全攻略

知道吗&#xff0c;很多人第一眼看到“基于Spring Boot的商场多功能折扣系统”这个毕设题目时&#xff0c;心里想的是&#xff1a;这不就一个打折功能嘛&#xff0c;商品表、订单表建一建&#xff0c;结算的时候打个折&#xff0c;完事了。但真动手之后&#xff0c;库存、订单状…

作者头像 李华
网站建设 2026/10/9 5:21:53

Superpowers:面向中高级开发者的AI编码增强工作流

1. “Superpowers”不是魔法&#xff0c;是开发者工具链的智能增强层你最近在技术社区、GitHub Trending 或 Discord 开发者频道里频繁看到superpowers这个词——它不像“React”或“Docker”那样指向某个具体框架或运行时&#xff0c;也不像“LLM”那样是个通用技术概念。它更…

作者头像 李华
网站建设 2026/10/9 5:17:18

面试官问“最复杂的项目”怎么答?避开三大雷区首句就赢

面试官一句“聊聊你最复杂的项目”&#xff0c;为什么很多人还没进入正题&#xff0c;第一句话就完了&#xff1f;这个问题的杀伤力在于&#xff1a;它看似开放&#xff0c;实际是一道披着闲聊外衣的“压力面”题目。我在不同场合模拟过几十场面试&#xff0c;也在真实面试里听…

作者头像 李华