下面以 Python 列表(list) 和 Java 集合框架 (以 ArrayList 和 HashSet 为代表)进行对比,帮助你从 Java 背景理解 Python 的列表特性。
1. 概念区分
- Python 列表 :一种有序、可变、可重复的序列类型,可以存放任意类型的元素(混合类型)。
- Java 集合 :是一个框架,包含多种接口和实现类:
List(如ArrayList):有序、可重复、可变。Set(如HashSet):无序、不可重复。Queue/Deque等。
在 Java 中"集合"通常泛指
Collection及其子接口;而 Python 的list更接近于 Java 的ArrayList,但功能更强。
2. 核心差异对比表
| 特性 | Python list |
Java ArrayList |
Java HashSet |
|---|---|---|---|
| 有序性 | ✅ 保持插入顺序 | ✅ 保持插入顺序 | ❌ 无序(LinkedHashSet 有序) |
| 允许重复 | ✅ 允许 | ✅ 允许 | ❌ 不允许 |
| 元素类型 | 可混合(如 [1, "a", True]) |
泛型统一(如 ArrayList<String>) |
泛型统一 |
| 可变性 | ✅ 可变 | ✅ 可变 | ✅ 可变 |
| null 元素 | ✅ 允许 | ✅ 允许 | ✅ 允许(通常一个 null) |
| 初始容量 | 动态自动扩容 | 可指定初始容量,自动扩容 | 可指定初始容量,自动扩容 |
| 线程安全 | ❌ 不安全 | ❌ 不安全(可用 CopyOnWriteArrayList) |
❌ 不安全(可用 ConcurrentHashMap 等) |
| 添加元素 | append(x) 或 + 运算符 |
add(x) |
add(x) |
| 插入指定位置 | insert(i, x) |
add(i, x) |
不支持 |
| 删除元素 | pop(i) 或 remove(x) |
remove(i) 或 remove(Object) |
remove(x) |
| 获取元素 | lst[i](O(1)) |
get(i)(O(1)) |
不支持按索引 |
| 包含检查 | x in lst(O(n)) |
contains(x)(O(n)) |
contains(x)(O(1) 平均) |
| 长度 | len(lst) |
size() |
size() |
| 遍历 | for item in lst: |
for (T item : list) |
for (T item : set) |
| 列表推导式 | ✅ [x*2 for x in lst] |
❌ 需用 Stream 或循环 | ❌ 需用 Stream |
| 切片操作 | ✅ lst[1:3] 返回新列表 |
❌ 需用 subList(视图) |
❌ 不支持 |
| 负数索引 | ✅ lst[-1] 最后一个 |
❌ 不支持 | ❌ 不支持 |
| 拼接 | lst1 + lst2 返回新列表 |
addAll(collection) |
addAll(collection) |
| 复制 | lst[:] 或 lst.copy() |
new ArrayList<>(original) |
new HashSet<>(original) |
3. 代码示例对比
Python 列表
python
# 创建混合类型列表
lst = [1, "hello", 3.14, True]
print(lst[0]) # 1
print(lst[-1]) # True
# 添加元素
lst.append("new")
lst.insert(1, 99)
# 删除
lst.pop() # 删除末尾
lst.remove("hello") # 删除指定值
# 切片
sub = lst[1:3]
# 列表推导式
squares = [x**2 for x in range(10) if x % 2 == 0]
# 包含检查
if 99 in lst:
print("found")
Java ArrayList
java
// 创建统一类型列表
List<String> list = new ArrayList<>();
list.add("hello");
list.add("world");
System.out.println(list.get(0)); // hello
// 没有负数索引
// 添加
list.add(1, "insert");
// 删除
list.remove(list.size() - 1); // 删除末尾
list.remove("hello"); // 删除指定值
// 切片(视图,不是新列表)
List<String> sub = list.subList(1, 3);
// 列表推导式不存在,用 Stream
List<Integer> squares = IntStream.range(0, 10)
.filter(i -> i % 2 == 0)
.map(i -> i * i)
.boxed()
.collect(Collectors.toList());
// 包含检查
if (list.contains("hello")) {
System.out.println("found");
}
4. 典型使用场景
| 场景 | Python 推荐 | Java 推荐 |
|---|---|---|
| 有序、可重复、频繁按索引访问 | list |
ArrayList |
| 有序、可重复、频繁在头部插入/删除 | collections.deque |
LinkedList |
| 无序、不可重复、快速查找 | set |
HashSet |
| 有序、不可重复 | dict(3.7+ 有序)或用 list 手动去重 |
LinkedHashSet |
| 线程安全 | queue.Queue 或手动加锁 |
CopyOnWriteArrayList, ConcurrentHashMap |
5. 总结:Python 列表的独特优势
- 语法简洁 :负数索引、切片、列表推导式、
in运算符。 - 类型灵活:一个列表可以同时存放数字、字符串、对象、甚至其他列表。
- 无需导入 :列表是内置类型,而 Java 的
ArrayList需要import java.util.*。 - 自动处理扩容:与 Java 类似,但无需显式指定泛型。
如果你熟悉 Java 的
ArrayList,那么 Python 的list可以看作它的"超级增强版",额外多了很多方便操作。但要注意 Python 列表不是哈希表 ,成员检查in的时间复杂度是 O(n),而 Java 的HashSet是 O(1)。对于需要快速查找去重的场景,Python 应使用set。