Java集合框架 vs Python数据结构:一张表格搞定转换
摘要:Java有ArrayList、HashMap、HashSet,Python有list、dict、set。看似相似的数据结构,API设计却大相径庭。
写在前面
Java的标准集合框架设计精巧但略显复杂,需要区分List/Set/Map三大接口,每种又有多种实现。Python的设计思路完全不同——简单、直观。
对Java工程师来说,最大的挑战不是"怎么用",而是"忘掉Java的习惯"。
一、整体对比一览
| Java | Python | 说明 |
|---|
List<T> | list | 有序可重复 |
Set<T> | set | 无序不重复 |
Map<K,V> | dict | 键值对 |
Queue | queue/collections.deque | 队列 |
Stack | list | 栈(用append/pop) |
LinkedList<T> | collections.deque | 双端队列 |
二、List列表对比
2.1 创建与初始化
List<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");
List<Integer> nums = Arrays.asList(1, 2, 3);
lst = []
lst = list()
lst = ["apple", "banana"]
nums = [1, 2, 3]
nums = list(range(5))
2.2 常用操作对比
| 操作 | Java | Python |
|---|
| 添加元素 | list.add(item) | list.append(item) / list.insert(i, item) |
| 获取元素 | list.get(i) | list[i] |
| 设置元素 | list.set(i, item) | list[i] = item |
| 删除元素 | list.remove(i) 或 list.remove(obj) | del list[i] / list.remove(obj) |
| 切片 | 无直接对应 | list[start:stop:step] |
| 长度 | list.size() | len(list) |
| 遍历 | for (String item : list) | for item in list: |
| 索引 | list.indexOf(item) | list.index(item) |
| 包含检查 | list.contains(item) | item in list |
| 排序 | Collections.sort(list) | list.sort() 或 sorted(list) |
| 反转 | Collections.reverse(list) | list.reverse() |
| 清空 | list.clear() | list.clear() |
2.3 切片操作(Python独有)
lst = [0, 1, 2, 3, 4, 5]
lst[1:4]
lst[::2]
lst[::-1]
lst[2:]
lst[:3]
2.4 列表推导式(Python特色)
List<Integer> squares = new ArrayList<>();
for (int i = 0; i < 10; i++) {
squares.add(i * i);
}
// Java 8之后的写法
List<Integer> squares = IntStream.range(0, 10)
.map(i -> i * i)
.collect(Collectors.toList());
squares = [i * i for i in range(10)]
evens = [i for i in range(10) if i % 2 == 0]
pairs = [(x, y) for x in range(3) for y in range(3)]
三、Map字典对比
3.1 创建与初始化
Map<String, Integer> map = new HashMap<>();
map.put("apple", 1);
map.put("banana", 2);
Map<String, Integer> map = Map.of("apple", 1, "banana", 2);
d = {}
d = dict()
d = {"apple": 1, "banana": 2}
d = dict.fromkeys(["a", "b", "c"], 0)
d = {k: v for k, v in [("apple", 1), ("banana", 2)]}
3.2 常用操作对比
| 操作 | Java | Python |
|---|
| 添加/更新 | map.put(k, v) | map[k] = v 或 map.update({k: v}) |
| 获取值 | map.get(k) | map[k](键不存在会抛异常)或 map.get(k, default) |
| 获取值(安全) | map.getOrDefault(k, default) | map.get(k, default) |
| 删除 | map.remove(k) | del map[k] 或 map.pop(k) |
| 检查键 | map.containsKey(k) | k in map |
| 检查值 | map.containsValue(v) | v in map.values() |
| 遍历键 | map.keySet() | for k in map: |
| 遍历值 | map.values() | for v in map.values(): |
| 遍历键值对 | map.entrySet() | for k, v in map.items(): |
| 长度 | map.size() | len(map) |
| 清空 | map.clear() | map.clear() |
3.3 遍历对比
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
map.forEach((k, v) -> System.out.println(k + " = " + v));
for k, v in map.items():
print(f"{k} = {v}")
squares = {x: x*x for x in range(5)}
四、Set集合对比
4.1 创建与初始化
Set<String> set = new HashSet<>();
set.add("apple");
set.add("banana");
s = set()
s = {"apple", "banana"}
s = set(["apple", "banana"])
4.2 常用操作对比
| 操作 | Java | Python |
|---|
| 添加 | set.add(item) | set.add(item) |
| 删除 | set.remove(item)(不存在抛异常) | set.remove(item)(不存在抛异常)或 set.discard(item) |
| 交集 | set1.retainAll(set2) | set1 & set2 或 set1.intersection(set2) |
| 并集 | set1.addAll(set2) | set1 | set2 或 set1.union(set2) |
| 差集 | set1.removeAll(set2) | set1 - set2 或 set1.difference(set2) |
| 包含 | set.contains(item) | item in set |
| 子集 | set1.containsAll(set2) | set1 <= set2 或 set1.issubset(set2) |
| 超集 | set1.containsAll(set2) | set1 >= set2 或 set1.issuperset(set2) |
五、Queue队列对比
5.1 Java的Queue体系
Queue<String> queue = new LinkedList<>();
queue.offer("first");
String head = queue.poll();
Queue<Integer> pq = new PriorityQueue<>(Comparator.reverseOrder());
5.2 Python的队列
from collections import deque
queue = deque()
queue.append("first")
queue.append("second")
head = queue.popleft()
stack = deque()
stack.append("a")
stack.append("b")
top = stack.pop()
5.3 队列操作对比
| 操作 | Java | Python |
|---|
| 入队 | queue.offer(item) | queue.append(item) |
| 出队 | queue.poll() | queue.popleft() |
| 查看队首 | queue.peek() | queue[0] |
| 长度 | queue.size() | len(queue) |
| 是否为空 | queue.isEmpty() | not queue |
六、实战对比
6.1 词频统计
public Map<String, Integer> wordCount(List<String> words) {
Map<String, Integer> counts = new HashMap<>();
for (String word : words) {
counts.merge(word, 1, Integer::sum);
}
return counts;
}
from collections import Counter
def word_count(words):
return Counter(words)
def word_count(words):
counts = {}
for word in words:
counts[word] = counts.get(word, 0) + 1
return counts
6.2 去重并保持顺序
public <T> List<T> distinct(List<T> list) {
return new ArrayList<>(new LinkedHashSet<>(list));
}
def distinct(lst):
return list(dict.fromkeys(lst))
七、避坑指南
7.1 可变默认参数陷阱
def add_item(item, result=[]):
result.append(item)
return result
print(add_item("a"))
print(add_item("b"))
def add_item(item, result=None):
if result is None:
result = []
result.append(item)
return result
7.2 引用传递注意事项
original = [1, 2, 3]
copied = original
copied.append(4)
print(original)
shallow_copy = original.copy()
deep_copy = copy.deepcopy(original)
八、总结
| 场景 | Java写法 | Python写法 |
|---|
| 创建列表 | new ArrayList<>() | [] 或 list() |
| 快速判断包含 | list.contains() | item in list |
| 字典遍历 | for (Map.Entry...) | for k, v in dict.items() |
| 集合交集 | set1.retainAll(set2) | set1 & set2 |
| 过滤元素 | Stream API | list comprehension |
| 统计词频 | HashMap手动累加 | Counter |
Python的数据结构设计追求"最简单的操作就用最简单的方式"。Java强调接口抽象和实现分离,Python强调直觉和简洁。