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 特点

  • 底层是链表
  • 头尾插入、删除方便
  • 也可以当作 QueueDeque 使用
  • 随机访问效率不高

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()); // 20
System.out.println(stack.pop());  // 20

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()); // 1
System.out.println(queue.poll()); // 1

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()); // 3
System.out.println(pq.poll()); // 3

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)); // 3
System.out.println(set.floor(4));   // 3

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)); // 3
System.out.println(map.floorKey(4));   // 3

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 先记“是否有序”

  • TreeSetTreeMap 是有序的
  • HashSetHashMap 是无序的

13.2 先记“是否允许重复”

  • HashSetTreeSet 不允许重复
  • HashMapTreeMap 的 key 不允许重复

13.3 先记“是否支持下标”

  • ArrayList 支持下标
  • LinkedList 虽然能按下标访问,但不适合频繁这样用
  • HashSetHashMap 不能按位置访问

13.4 先记“默认堆类型”

  • PriorityQueue 默认是小根堆

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 个函数”
  • 第二遍重点区分 HashMapTreeMapHashSetTreeSet
  • 刷题时最常用的通常是 ArrayListHashMapDequePriorityQueue
  • Java 刷题里 Deque 的使用频率通常非常高,值得重点记

更多推荐