📌 List 和 Set 的区别
在 Java 中,List
和 Set
都是 Collection 接口的子接口,但它们的存储结构、特点、使用场景不同。
对比项 | List(有序、可重复) | Set(无序、不可重复) |
---|---|---|
是否允许重复元素 | ✅ 允许 | ❌ 不允许 |
是否有序 | ✅ 按插入顺序排序 | ❌ 无序(TreeSet 除外) |
是否可以有 null |
✅ 允许多个 null |
✅ 只允许一个 null |
底层数据结构 | 数组、链表 | 哈希表、红黑树 |
访问方式 | 通过索引访问 | 通过 iterator 遍历 |
适用场景 | 需要顺序存储、允许重复元素 | 需要去重、快速查找 |
1️⃣ List 详解
List
是 有序且允许重复 的集合,主要实现类有:
ArrayList
(底层是数组,查询快,增删慢)LinkedList
(底层是链表,增删快,查询慢)Vector
(线程安全,性能较低)
💡 List 使用示例
import java.util.*;
public class ListExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Java");
list.add("Python");
list.add("Java"); // ✅ 允许重复
System.out.println(list); // [Java, Python, Java]
// 按索引访问
System.out.println(list.get(1)); // Python
}
}
📝 ArrayList
vs LinkedList
对比项 | ArrayList | LinkedList |
---|---|---|
底层结构 | 动态数组 | 双向链表 |
查询速度 | ✅ 快(O(1)) | ❌ 慢(O(n)) |
插入/删除速度 | ❌ 慢(O(n)) | ✅ 快(O(1) 或 O(n)) |
适用场景 | 读操作多的场景 | 增删操作多的场景 |
2️⃣ Set 详解
Set
是 无序且不允许重复 的集合,主要实现类有:
HashSet
(底层是HashMap
,无序)LinkedHashSet
(底层是LinkedHashMap
,有序)TreeSet
(底层是红黑树,自动排序)
💡 Set 使用示例
import java.util.*;
public class SetExample {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add("Java");
set.add("Python");
set.add("Java"); // ❌ 不允许重复
System.out.println(set); // 可能是 [Python, Java],但无序
}
}
📝 HashSet
vs TreeSet
对比项 | HashSet | TreeSet |
---|---|---|
底层结构 | 哈希表 | 红黑树 |
是否有序 | ❌ 无序 | ✅ 自动排序 |
查询速度 | ✅ 快(O(1)) | ❌ 慢(O(log n)) |
适用场景 | 需要快速去重 | 需要排序的集合 |
3️⃣ 什么时候用 List,什么时候用 Set?
✅ 使用 List
的情况:
- 需要 存储有序 的元素。
- 需要 允许重复 的元素。
- 需要 按索引访问 元素。
✅ 使用 Set
的情况:
- 需要 去重,不允许存储相同元素。
- 不关心存储顺序(除非用
LinkedHashSet
)。 - 需要 自动排序(使用
TreeSet
)。
🎯 结论
List
适用于存储有序、可重复的数据,可以按索引访问。Set
适用于存储无序、不可重复的数据,查询性能较优。