Python 数据结构(Java 对照)
这篇笔记是我从 Java 切到 Python 时,对常见数据结构做的一次对照整理。核心目标是两件事:
- 快速把 Java 里的习惯映射到 Python
- 避免在刷题和业务代码中踩性能和语义坑
总览对照
| 场景 | Java 常见写法 | Python 常见写法 |
|---|---|---|
| 动态数组 | ArrayList | list |
| 哈希映射 | HashMap | dict |
| 哈希集合 | HashSet | set |
| 栈 | ArrayDeque / Stack | list |
| 队列 / 双端队列 | ArrayDeque | collections.deque |
| 小顶堆 | PriorityQueue | heapq + list |
数组与动态列表(Array / ArrayList)
# Java: List<Integer> list = new ArrayList<>()
arr = []
# Java: list.add(1)
arr.append(1)
# Java: list.get(i)
arr[0]
# Java: list.size() / arr.length
len(arr)
# Java: list.remove(list.size() - 1)
arr.pop()
# Java: list.subList(start, end) # 左闭右开
sub = arr[start:end]
我补充的点:
- Python
list头部插入/删除是O(n),大量队列操作不要用它,改用deque - 切片
arr[a:b]会返回新列表,不是视图
哈希映射(HashMap / Dict)
# Java: Map<String, Integer> map = new HashMap<>()
tmap = {}
# Java: map.put("apple", 1)
tmap["apple"] = 1
# Java: map.containsKey("apple")
"apple" in tmap
# Java: map.get("apple")
# 注意:如果 key 不存在会抛 KeyError
tmap["apple"]
# Java: map.getOrDefault("apple", 0)
tmap.get("apple", 0)
# Java: map.remove("apple")
del tmap["apple"]
# Java: for (String key : map.keySet())
for key in tmap:
pass
# Java: for (Map.Entry<String, Integer> entry : map.entrySet())
for key, value in tmap.items():
pass
我补充的点:
del tmap[k]在 key 不存在时会报错;更稳妥可以用tmap.pop(k, None)- 高频计数建议直接用
collections.Counter或defaultdict(int)
哈希集合(HashSet / Set)
# Java: Set<Integer> set = new HashSet<>()
tset = set()
# Java: set.add(1)
tset.add('a')
# Java: set.contains(1)
'a' in tset
# Java: set.remove(1) # 不存在会报错
tset.remove('a')
# Python 专属:不存在不报错
tset.discard('a')
# Java: set.size()
len(tset)
我补充的点:
set无序,不要依赖迭代顺序- 去重保序要用
dict.fromkeys(seq)或手动维护
栈与双端队列(Deque / Stack / Queue)
from collections import deque
# 栈(后进先出)
# Java: Deque<Integer> stack = new ArrayDeque<>()
stack = []
stack.append(1) # push
stack.pop() # pop
# peek 前先判空
if stack:
top = stack[-1]
# 队列(先进先出)
# Java: Deque<Integer> queue = new ArrayDeque<>()
queue = deque()
queue.append(1) # addLast
queue.appendleft(2) # addFirst
queue.popleft() # pollFirst
queue.pop() # pollLast
if queue:
head = queue[0] # peekFirst
if not queue:
pass
我补充的点:
- Python 里“队列”优先用
deque,不要用list.pop(0) - 访问栈顶/队头前先判空,避免
IndexError
堆 / 优先队列(PriorityQueue / Heap)
import heapq
# Java: PriorityQueue<Integer> pq = new PriorityQueue<>()
heap = []
heapq.heappush(heap, 5) # offer
heapq.heappush(heap, 2)
heapq.heappop(heap) # poll
# peek
if heap:
top = heap[0]
# Python 只内置小顶堆
# Java maxHeap: new PriorityQueue<>((a, b) -> b - a)
max_heap = []
heapq.heappush(max_heap, -5)
heapq.heappush(max_heap, -2)
val = -heapq.heappop(max_heap)
我补充的点:
heapq不是完整容器类,而是“对 list 做堆操作的函数集”- 想要固定容量 topK,常用“小顶堆保留 K 个元素”
我常用的安全写法模板
# dict 安全读取
v = tmap.get("k", 0)
# dict 安全删除
tmap.pop("k", None)
# 栈/队列取值前判空
if stack:
x = stack[-1]
if queue:
y = queue[0]
# 堆顶读取前判空
if heap:
z = heap[0]
阶段总结
从 Java 切到 Python 后,我的主要变化是:
- 少关注“类名”,多关注“操作复杂度”
- 队列优先
deque,堆优先heapq - 字典和集合的“存在性判断 + 安全访问”写法要形成肌肉记忆
后续我会继续补一篇:排序 / 二分 / 前缀和 / 单调栈 在 Python 里的模板化写法。