摘要
Java 集合是面试里非常高频的基础题。这个问题看起来简单,但很多人一答就容易把 Collection、Collections、List、Set、Map、Iterator 混在一起。本文用面试视角,快速梳理 Java 集合体系、常见分类、核心区别和高频追问,适合面试前快速复习。
前言
最近这段时间工作比较忙,一直没怎么更新文章。
但我发现一个问题:越忙的时候,越容易把一些基础知识忘得差不多。尤其是 Java 面试八股,平时写业务代码的时候感觉都懂,但真到面试被问起来,如果没有提前梳理,很容易答得又散又乱。
所以我准备开一个偏“速记型”的 Java 面试系列。
不追求写得特别长,也不搞太多废话,主要就是:
面试常问什么,应该怎么答,哪些点容易混,最后怎么用一段话说清楚。
第一篇就从 Java 集合开始。
Java 集合是面试里非常高频的基础题,尤其是 List、Set、Map、Collection、Collections、Iterator 这些概念,经常会被放在一起问。
一、面试官一般会怎么问?
集合类这个知识点,面试官通常会这么问:
- Java 中常见的集合类有哪些?
List、Set、Map有什么区别?Collection和Collections有什么区别?ArrayList和LinkedList有什么区别?HashMap和Hashtable有什么区别?Iterator和Iterable有什么关系?- 为什么集合可以用 foreach 遍历?
这篇先不展开所有集合底层原理,先把集合体系和分类讲清楚。
二、先给结论:Java 集合主要分两套体系
Java 集合大体可以分成两套体系:
CollectionMap
其中:
Collection 用来存放单个元素。
它下面常见的子接口有:
ListSetQueue
Map 用来存放 key-value 键值对。
它不属于 Collection 体系。
可以简单理解成:
Java 集合体系
├── Collection
│ ├── List
│ ├── Set
│ └── Queue
└── Map
面试时不要把 Map 说成 Collection 的子接口,这个是基础但容易嘴瓢的点。
三、Collection 体系有哪些?
Collection 是 Java 集合框架中的一个顶层接口,它表示一组对象。
常见子接口主要有三个。
1. List
List 的特点是:
- 有序
- 可重复
- 可以通过下标访问
常见实现类:
ArrayListLinkedListVector
简单理解:
List更像一个列表,元素可以重复,并且有插入顺序。
示例:
List<String> list = new ArrayList<>();
list.add("Java");
list.add("Spring");
list.add("Java");
System.out.println(list);
输出:
[Java, Spring, Java]
可以看到,List 允许重复元素。
2. Set
Set 的特点是:
- 不允许重复
- 通常无序
- 不能通过下标访问
常见实现类:
HashSetLinkedHashSetTreeSet
简单理解:
Set更像一个去重集合,主要用来保证元素不重复。
示例:
Set<String> set = new HashSet<>();
set.add("Java");
set.add("Spring");
set.add("Java");
System.out.println(set);
输出结果中只会保留一个 Java。
需要注意的是:
HashSet 的底层其实是基于 HashMap 实现的。
这一点后面讲 HashMap 的时候可以展开。
3. Queue
Queue 表示队列结构。
它的特点是:
- 通常用于先进先出
- 也可以支持优先级队列
- 常用于任务排队、消息处理等场景
常见实现类:
LinkedListPriorityQueueArrayDeque
简单理解:
Queue更适合表达排队处理的场景。
示例:
Queue<String> queue = new LinkedList<>();
queue.offer("task1");
queue.offer("task2");
System.out.println(queue.poll());
System.out.println(queue.poll());
输出:
task1
task2
四、Map 体系有哪些?
Map 和 Collection 不一样。
Map 存的是 key-value 键值对。
常见实现类:
HashMapLinkedHashMapTreeMapHashtableConcurrentHashMap
简单理解:
Map适合根据 key 快速查找 value。
示例:
Map<String, Integer> map = new HashMap<>();
map.put("Java", 1);
map.put("Spring", 2);
System.out.println(map.get("Java"));
输出:
1
Map 最常见的使用场景就是:
- 根据用户 ID 查用户信息
- 根据编码查名称
- 根据 key 缓存某个对象
- 根据业务标识做映射
五、List、Set、Queue、Map 有什么区别?
这个问题很常见,面试时可以用表格记。
| 类型 | 是否有序 | 是否允许重复 | 典型特点 | 常见实现 | | --- | --- | --- | --- | --- | | List | 有序 | 允许重复 | 有下标,适合按顺序存储 | ArrayList、LinkedList | | Set | 不保证有序 | 不允许重复 | 适合去重 | HashSet、TreeSet | | Queue | 通常有序 | 允许重复 | 队列结构,适合排队处理 | LinkedList、PriorityQueue | | Map | key 不允许重复 | value 可重复 | key-value 键值对 | HashMap、TreeMap、ConcurrentHashMap |
面试时可以这样回答:
List 主要特点是有序、可重复,可以通过下标访问;
Set 主要特点是不允许重复,常用于去重;
Queue 偏队列结构,适合先进先出或优先级队列场景;
Map 存储的是 key-value 键值对,适合根据 key 快速查询 value。
六、Collection 和 Collections 有什么区别?
这个是经典基础题。
一句话:
Collection是集合接口,Collections是集合工具类。
1. Collection
Collection 是 Java 集合框架中的接口。
List、Set、Queue 都是它的子接口。
2. Collections
Collections 是工具类。
它里面提供了很多操作集合的静态方法,比如:
- 排序
- 反转
- 打乱
- 查找最大值
- 查找最小值
- 创建线程安全集合
示例:
List<Integer> list = new ArrayList<>();
list.add(3);
list.add(1);
list.add(2);
Collections.sort(list);
System.out.println(list);
输出:
[1, 2, 3]
面试回答:
Collection 是集合体系中的顶层接口之一,List、Set、Queue 都属于它的子体系。
Collections 是一个工具类,里面提供了很多操作集合的静态方法,比如排序、反转、查找、同步包装等。
简单记就是:Collection 是接口,Collections 是工具类。
七、Iterable 和 Iterator 有什么区别?
这个也经常被问。
一句话:
Iterable表示这个对象可以被遍历,Iterator是真正执行遍历的迭代器。
1. Iterable
Iterable 是可迭代接口。
只要一个类实现了 Iterable,就可以使用 foreach 遍历。
比如:
List<String> list = new ArrayList<>();
list.add("Java");
list.add("Spring");
for (String item : list) {
System.out.println(item);
}
之所以 List 能用 foreach,是因为它属于 Collection 体系,而 Collection 继承了 Iterable。
2. Iterator
Iterator 是迭代器接口。
它主要有几个常见方法:
hasNext()next()remove()
示例:
List<String> list = new ArrayList<>();
list.add("Java");
list.add("Spring");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
System.out.println(item);
}
面试回答:
Iterable 表示一个对象具备被遍历的能力,实现了 Iterable 的类可以使用 foreach。
Iterator 是真正执行遍历过程的迭代器,常见方法有 hasNext()、next()、remove()。
简单理解就是:Iterable 说明能遍历,Iterator 负责怎么遍历。
八、为什么 Collection 要继承 Iterable?
因为集合本质上就是一组元素。
既然是元素集合,就应该具备统一的遍历能力。
所以 Collection 继承了 Iterable,这样它下面的 List、Set、Queue 都可以通过统一方式遍历。
面试时可以这样说:
Collection 继承 Iterable,是为了让集合体系具备统一的遍历能力。
这样 List、Set、Queue 等集合都可以通过 Iterator 或 foreach 的方式遍历,使用方式更加统一。
九、foreach 的底层和 Iterator 有什么关系?
foreach 本质上是一种语法糖。
对于实现了 Iterable 的集合,foreach 底层还是通过 Iterator 来完成遍历。
比如我们写:
for (String item : list) {
System.out.println(item);
}
大致可以理解成:
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
System.out.println(item);
}
所以面试时如果被问:
为什么集合可以用 foreach?
可以回答:
因为 Collection 继承了 Iterable,而 Iterable 提供了 iterator() 方法。
foreach 遍历集合时,底层会通过 Iterator 来完成遍历。
十、面试回答模板
如果面试官问:
Java 中的集合类有哪些?怎么分类?
可以这样答:
Java 集合大体可以分为 Collection 和 Map 两套体系。
Collection 用来存储单个元素,常见子接口有 List、Set、Queue。
List 的特点是有序、可重复,比如 ArrayList、LinkedList;
Set 的特点是不允许重复,比如 HashSet、TreeSet;
Queue 偏队列结构,比如 LinkedList、PriorityQueue。
Map 存储的是 key-value 键值对,不属于 Collection 体系。
常见实现有 HashMap、LinkedHashMap、TreeMap、ConcurrentHashMap。
另外需要注意 Collection 和 Collections 的区别:
Collection 是集合接口,Collections 是集合工具类。
这段回答不算特别深,但足够清楚。
如果面试官继续追问,再展开具体实现类的区别,比如:
ArrayList和LinkedListHashMap和HashtableHashMap和ConcurrentHashMapHashSet为什么能去重
十一、常见追问整理
1. ArrayList 和 LinkedList 有什么区别?
简单说:
ArrayList底层是数组LinkedList底层是链表
区别:
ArrayList查询快,增删可能慢LinkedList插入删除相对方便,但查询需要遍历
一句话:
ArrayList 适合查询多的场景,LinkedList 适合插入删除多的场景。
但实际开发中,ArrayList 用得更多。
2. HashSet 为什么能去重?
因为 HashSet 底层基于 HashMap 实现。
添加元素时,元素会作为 HashMap 的 key 存进去。
而 HashMap 的 key 不能重复,所以 HashSet 能去重。
一句话:
HashSet 去重依赖 HashMap 的 key 不重复,本质上还和 hashCode()、equals() 有关。
3. HashMap 是不是线程安全的?
不是。
HashMap 不是线程安全的。
多线程场景下,如果多个线程同时修改 HashMap,可能出现数据覆盖、数据不一致等问题。
多线程场景一般考虑:
ConcurrentHashMap- 或者额外加锁
一句话:
HashMap 适合单线程或局部变量场景,多线程共享修改时应该使用 ConcurrentHashMap。
4. Vector 为什么现在用得少?
Vector 是早期的线程安全 List 实现。
它的方法很多都加了 synchronized,所以线程安全,但性能相对较差。
现在实际开发中更常用:
ArrayListCopyOnWriteArrayList- 或者自己控制并发场景
一句话:
Vector 比较老,虽然线程安全,但并发性能和使用灵活性都不如现在常用的并发集合。
十二、一句话总结
Java 集合大体分为 Collection 和 Map 两套体系。
Collection 存单个元素,常见的有 List、Set、Queue;
Map 存 key-value 键值对,不属于 Collection 体系。
面试时先把分类讲清楚,再展开具体实现类的特点和区别。
这类题不难,但一定要答得有层次。
别一上来就把 ArrayList、HashMap、HashSet 全混在一起说。
大家加油:)