java collection 体系与使用场景整理
本文从抽象层级、接口设计、实际使用场景三个角度,系统说明什么是 collection,什么时候“面向 collection 创建对象”,什么时候应直接使用 list,以及何时选择其它集合类型(set、queue、map 等)。
一、什么是 collection
1. collection 的本质
collection<e> 是 java 集合框架(java collections framework, jcf)中最基础的集合接口之一,表示:
一组元素(element)的抽象集合
它只关心:
- 是否能存元素
- 是否能遍历
- 是否能删除
- 是否包含某元素
而不关心:
- 是否有顺序
- 是否允许重复
- 是否支持索引
2. collection 在体系中的位置
iterable ↑ collection ↑ ├── list ├── set └── queue
collection 是 list / set / queue 的共同父接口,但 不包含索引、顺序、唯一性等语义。
二、为什么要有 collection 这种“看起来没什么用”的接口
1. 抽象层面的意义
collection 的存在是为了:
- 统一抽象:对“元素集合”进行最小能力抽象
- 解耦实现:调用方不关心底层是
arraylist、linkedlist、hashset - 支持多态:同一段代码可处理多种集合实现
示例:
void process(collection<string> c) {
for (string s : c) {
system.out.println(s);
}
}
这段代码:
- 可以接收
arraylist - 可以接收
hashset - 可以接收
linkedlist
2. collection 的“能力边界”
collection 刻意不提供以下能力:
- 索引访问(
get(int)) - 保证顺序
- 保证唯一性
因为:
- 并非所有集合都有这些语义
- 强行放入接口会破坏接口隔离原则(isp)
三、什么时候“创建 collection”
重要
collection 是接口,不能直接 new
真正创建的是:
collection<string> c = new arraylist<>();
这里的含义是:
- 编译期类型:
collection - 运行期类型:
arraylist
适合使用collection作为声明类型的场景
场景 1:方法参数(最典型)
void saveall(collection<user> users) {
...
}
理由:
- 方法不依赖“索引/顺序/唯一性”
- 调用方自由选择
list/set
list<user> l = new arraylist<>();
l.add("b");
l.add("c");
saveall(l);
这是 最推荐 的使用方式(就是多态的体现)。

场景 2:返回值只表达“一组元素”
collection<order> findorders() {
return new arraylist<>();
}
调用方:
- 只能遍历、判断、删除
- 不会错误依赖具体实现
场景 3:业务逻辑不关心集合语义
collection<string> tags = new hashset<>();
当你只需要:
- 存
- 遍历
- 不关心顺序和索引
四、什么时候必须使用 list
list 的核心语义
list<e> 表示:
有序、可重复、可按索引访问的集合
它在 collection 基础上增加了:
get(int index)set(int, e)add(int, e)
必须使用 list 的典型场景
场景 1:需要索引访问
list<string> list = new arraylist<>(); string first = list.get(0);
如果你需要 get(i),就不应该使用 collection 声明。
场景 2:需要顺序语义
list<string> steps = list.of("init", "load", "run");
顺序有业务含义(流程、步骤、时间线)。
场景 3:与 ui / json / dto 强绑定
- 前端列表
- json array
- excel 行
这些天然是 有序结构,应使用 list。
list 的常见实现选择
| 实现 | 适用场景 |
|---|---|
arraylist | 读多写少、随机访问多(默认首选) |
linkedlist | 频繁头尾插入/删除(但实际很少需要) |
五、什么时候使用 set
set 的核心语义
set<e> 表示:
不允许重复元素的集合
典型使用场景
- 去重
- 成员检测(contains)
- 数学集合语义
示例:
set<string> users = new hashset<>();
常见实现:
hashset:不保证顺序(最快)linkedhashset:保持插入顺序treeset:排序集合
六、什么时候使用 queue / deque
queue / deque 的语义
- queue:队列(fifo)
- deque:双端队列
使用场景
- 任务队列
- 消息缓冲
- bfs / 滑动窗口
示例:
queue<task> q = new arraydeque<>();
七、map 为什么不属于 collection
map 的本质
map<k, v> 表示:
键值对映射,不是“元素集合”
所以:
- 不继承
collection - 但可以通过
keyset()/values()/entryset()间接使用collection
八、总结
1. 面向接口编程
声明用接口,实现用具体类
list<string> list = new arraylist<>(); collection<string> c = new arraylist<>();
2. 用“最小能力接口”
- 需要索引 →
list - 需要去重 →
set - 只需遍历 →
collection
3. 不要因为“实现是 arraylist”就暴露 list
// 不推荐
public arraylist<string> getdata() { ... }
// 推荐
public list<string> getdata() { ... }九、一句话总结
- collection:只表示“一堆元素”,用于抽象、解耦、通用逻辑
- list:当顺序和索引是业务语义的一部分
- set:当唯一性是业务约束
- queue/deque:当访问顺序受限(fifo/lifo)
- map:当数据是“键 → 值”关系
接口表达“你需要什么能力”,实现类决定“怎么做到”。
到此这篇关于java collection 体系与使用场景整理的文章就介绍到这了,更多相关java collection使用内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论