Java 常用数据结构与函数整理
这份笔记参考 12_stl_common.md 的整理方式,按常见 Java 数据结构分类,适合刷题和复习时快速查阅。
1. ArrayList
1.1 特点
- 底层是动态数组
- 支持随机访问
- 尾部插入效率较高
- 中间插入、删除效率较低
1.2 常用定义
ArrayList<Integer> list = new ArrayList<>();
ArrayList<Integer> list2 = new ArrayList<>(List.of(1, 2, 3));
1.3 常用函数
| 函数 |
作用 |
list.size() |
返回元素个数 |
list.isEmpty() |
判断是否为空 |
list.add(x) |
尾部插入 |
list.add(i, x) |
在下标 i 处插入 |
list.get(i) |
获取下标 i 的元素 |
list.set(i, x) |
修改下标 i 的元素 |
list.remove(i) |
删除下标 i 的元素 |
list.remove(Integer.valueOf(x)) |
删除值为 x 的元素 |
list.clear() |
清空 |
list.contains(x) |
判断是否包含某元素 |
1.4 常见写法
ArrayList<Integer> list = new ArrayList<>();
list.add(3);
list.add(1);
list.add(4);
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i) + " ");
}
for (int x : list) {
System.out.print(x + " ");
}
1.5 常用算法配合
Collections.sort(list);
Collections.sort(list, Collections.reverseOrder());
Collections.reverse(list);
1.6 易错点
remove(i) 和 remove(x) 很容易混淆
ArrayList<Integer> 中 remove(1) 默认表示删下标,不是删值
- 下标访问前要注意不要越界
2. LinkedList
2.1 特点
- 底层是链表
- 头尾插入、删除方便
- 也可以当作
Queue 或 Deque 使用
- 随机访问效率不高
2.2 常用定义
LinkedList<Integer> list = new LinkedList<>();
2.3 常用函数
| 函数 |
作用 |
list.add(x) |
尾插 |
list.addFirst(x) |
头插 |
list.addLast(x) |
尾插 |
list.removeFirst() |
删除头部 |
list.removeLast() |
删除尾部 |
list.getFirst() |
访问头部 |
list.getLast() |
访问尾部 |
list.size() |
元素个数 |
list.isEmpty() |
是否为空 |
list.clear() |
清空 |
2.4 示例
LinkedList<Integer> list = new LinkedList<>();
list.addFirst(2);
list.addLast(5);
System.out.println(list.getFirst());
System.out.println(list.getLast());
2.5 易错点
- 不适合频繁按下标访问
- 空链表调用
getFirst()、removeFirst() 会报异常
3. Stack
3.1 特点
- 栈,后进先出
- 主要操作栈顶元素
- 刷题里也常用
Deque 来模拟栈
3.2 常用定义
Stack<Integer> stack = new Stack<>();
3.3 常用函数
| 函数 |
作用 |
stack.push(x) |
入栈 |
stack.pop() |
出栈并返回栈顶 |
stack.peek() |
查看栈顶 |
stack.isEmpty() |
是否为空 |
stack.size() |
元素个数 |
3.4 示例
Stack<Integer> stack = new Stack<>();
stack.push(10);
stack.push(20);
System.out.println(stack.peek());
System.out.println(stack.pop());
3.5 易错点
- 空栈调用
pop()、peek() 会报异常
- Java 刷题中很多人更推荐用
Deque<Integer> 实现栈
4. Queue
4.1 特点
- 队列,先进先出
- 常用于 BFS
- Java 中通常用接口
Queue 配合实现类 LinkedList
4.2 常用定义
Queue<Integer> queue = new LinkedList<>();
4.3 常用函数
| 函数 |
作用 |
queue.offer(x) |
入队 |
queue.poll() |
出队并返回队头 |
queue.peek() |
查看队头 |
queue.isEmpty() |
是否为空 |
queue.size() |
元素个数 |
4.4 示例
Queue<Integer> queue = new LinkedList<>();
queue.offer(1);
queue.offer(2);
System.out.println(queue.peek());
System.out.println(queue.poll());
4.5 易错点
poll() 空队列时返回 null
remove() 也能删队头,但空队列时会抛异常,刷题时通常更喜欢 poll()
5. Deque
5.1 特点
- 双端队列
- 头尾都可以插入删除
- 可以同时模拟栈和队列
- Java 刷题中非常常用
5.2 常用定义
Deque<Integer> deque = new ArrayDeque<>();
5.3 常用函数
| 函数 |
作用 |
deque.offerFirst(x) |
头插 |
deque.offerLast(x) |
尾插 |
deque.pollFirst() |
头删并返回 |
deque.pollLast() |
尾删并返回 |
deque.peekFirst() |
查看队头 |
deque.peekLast() |
查看队尾 |
deque.push(x) |
当栈用,入栈 |
deque.pop() |
当栈用,出栈 |
deque.peek() |
当栈用,查看栈顶 |
deque.isEmpty() |
是否为空 |
deque.size() |
元素个数 |
5.4 示例
Deque<Integer> deque = new ArrayDeque<>();
deque.offerLast(1);
deque.offerFirst(2);
System.out.println(deque.peekFirst());
System.out.println(deque.peekLast());
5.5 易错点
ArrayDeque 不允许存 null
- 如果是刷题,
Deque 往往比老的 Stack 更推荐
6. PriorityQueue
6.1 特点
- 优先队列,本质是堆
- 默认是小根堆
- 常用于最值维护、Top K、贪心
6.2 常用定义
PriorityQueue<Integer> pq = new PriorityQueue<>();
大根堆写法:
PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> b - a);
6.3 常用函数
| 函数 |
作用 |
pq.offer(x) |
插入元素 |
pq.poll() |
删除并返回堆顶 |
pq.peek() |
查看堆顶 |
pq.isEmpty() |
是否为空 |
pq.size() |
元素个数 |
6.4 示例
PriorityQueue<Integer> pq = new PriorityQueue<>();
pq.offer(3);
pq.offer(10);
pq.offer(5);
System.out.println(pq.peek());
System.out.println(pq.poll());
6.5 易错点
- Java 默认是小根堆,不是大根堆
- 不能保证遍历结果有序
- 自定义比较器时要注意避免减法比较溢出
7. HashSet
7.1 特点
- 无序集合
- 元素不重复
- 底层是哈希表
- 平均查找、插入、删除较快
7.2 常用定义
HashSet<Integer> set = new HashSet<>();
7.3 常用函数
| 函数 |
作用 |
set.add(x) |
插入元素 |
set.remove(x) |
删除元素 |
set.contains(x) |
判断是否存在 |
set.size() |
元素个数 |
set.isEmpty() |
是否为空 |
set.clear() |
清空 |
7.4 示例
HashSet<Integer> set = new HashSet<>();
set.add(10);
set.add(20);
set.add(10);
System.out.println(set.contains(10));
7.5 易错点
8. TreeSet
8.1 特点
- 有序集合
- 元素不重复
- 底层一般是红黑树
- 支持范围查找
8.2 常用定义
TreeSet<Integer> set = new TreeSet<>();
8.3 常用函数
| 函数 |
作用 |
set.add(x) |
插入 |
set.remove(x) |
删除 |
set.contains(x) |
判断是否存在 |
set.first() |
最小值 |
set.last() |
最大值 |
set.ceiling(x) |
第一个大于等于 x 的元素 |
set.floor(x) |
第一个小于等于 x 的元素 |
set.higher(x) |
第一个大于 x 的元素 |
set.lower(x) |
第一个小于 x 的元素 |
set.size() |
元素个数 |
set.isEmpty() |
是否为空 |
8.4 示例
TreeSet<Integer> set = new TreeSet<>();
set.add(3);
set.add(1);
set.add(5);
System.out.println(set.ceiling(2));
System.out.println(set.floor(4));
8.5 易错点
- 自动排序,不保留插入顺序
- 如果查不到,
ceiling()、floor() 可能返回 null
9. HashMap
9.1 特点
- 无序键值对容器
- key 不重复
- 底层是哈希表
- 平均复杂度较低
9.2 常用定义
HashMap<String, Integer> map = new HashMap<>();
9.3 常用函数
| 函数 |
作用 |
map.put(key, value) |
插入或修改 |
map.get(key) |
获取 value |
map.getOrDefault(key, defaultValue) |
获取值,不存在返回默认值 |
map.remove(key) |
删除 key |
map.containsKey(key) |
判断 key 是否存在 |
map.containsValue(value) |
判断 value 是否存在 |
map.size() |
元素个数 |
map.isEmpty() |
是否为空 |
map.clear() |
清空 |
9.4 示例
HashMap<String, Integer> map = new HashMap<>();
map.put("alice", 95);
map.put("bob", 88);
System.out.println(map.get("alice"));
System.out.println(map.getOrDefault("cat", 0));
9.5 易错点
get(key) 查不到时返回 null
- 计数时更推荐
getOrDefault()
- 遍历顺序不固定
10. TreeMap
10.1 特点
- 有序键值对容器
- 按 key 自动升序排列
- key 不重复
- 支持范围查询
10.2 常用定义
TreeMap<Integer, String> map = new TreeMap<>();
10.3 常用函数
| 函数 |
作用 |
map.put(key, value) |
插入或修改 |
map.get(key) |
获取值 |
map.remove(key) |
删除 |
map.containsKey(key) |
判断 key 是否存在 |
map.firstKey() |
最小 key |
map.lastKey() |
最大 key |
map.ceilingKey(key) |
第一个大于等于 key 的键 |
map.floorKey(key) |
第一个小于等于 key 的键 |
map.higherKey(key) |
第一个大于 key 的键 |
map.lowerKey(key) |
第一个小于 key 的键 |
map.size() |
元素个数 |
10.4 示例
TreeMap<Integer, String> map = new TreeMap<>();
map.put(3, "c");
map.put(1, "a");
map.put(5, "e");
System.out.println(map.ceilingKey(2));
System.out.println(map.floorKey(4));
10.5 易错点
- 自动按 key 排序
- 查不到时相关函数可能返回
null
11. 常用遍历方式总结
11.1 遍历 ArrayList
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i) + " ");
}
for (int x : list) {
System.out.print(x + " ");
}
11.2 遍历 HashSet
for (int x : set) {
System.out.print(x + " ");
}
11.3 遍历 HashMap
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
for (String key : map.keySet()) {
System.out.println(key + " " + map.get(key));
}
12. 常见使用场景速记
| 数据结构 |
适合场景 |
ArrayList |
最常用,存一组数据,支持随机访问 |
LinkedList |
头尾频繁插入删除 |
Stack |
括号匹配、单调栈 |
Queue |
BFS、层序遍历 |
Deque |
双端操作、单调队列、替代栈 |
PriorityQueue |
堆、Top K、最值维护 |
HashSet |
快速去重、快速查找 |
TreeSet |
去重且需要有序 |
HashMap |
计数、映射、频率统计 |
TreeMap |
需要按 key 有序维护映射 |
13. 学 Java 数据结构时最值得记住的几点
13.1 先记“是否有序”
TreeSet、TreeMap 是有序的
HashSet、HashMap 是无序的
13.2 先记“是否允许重复”
HashSet、TreeSet 不允许重复
HashMap、TreeMap 的 key 不允许重复
13.3 先记“是否支持下标”
ArrayList 支持下标
LinkedList 虽然能按下标访问,但不适合频繁这样用
HashSet、HashMap 不能按位置访问
13.4 先记“默认堆类型”
13.5 先记“空结构时返回什么”
poll()、peek() 一般更安全,空时常返回 null
pop()、remove()、getFirst() 之类空时常抛异常
14. 刷题最常用模板
14.1 ArrayList 排序
ArrayList<Integer> list = new ArrayList<>(List.of(4, 2, 5, 1));
Collections.sort(list);
14.2 HashMap 计数
HashMap<Integer, Integer> cnt = new HashMap<>();
for (int x : nums) {
cnt.put(x, cnt.getOrDefault(x, 0) + 1);
}
14.3 HashSet 去重
HashSet<Integer> set = new HashSet<>();
for (int x : nums) {
set.add(x);
}
14.4 大根堆
PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> b - a);
14.5 队列 BFS
Queue<Integer> queue = new LinkedList<>();
queue.offer(start);
while (!queue.isEmpty()) {
int x = queue.poll();
}
15. 复习建议
- 第一遍先记每种结构的“特点”和“最常用 5 个函数”
- 第二遍重点区分
HashMap 和 TreeMap、HashSet 和 TreeSet
- 刷题时最常用的通常是
ArrayList、HashMap、Deque、PriorityQueue
- Java 刷题里
Deque 的使用频率通常非常高,值得重点记
所有评论(0)