List 和 Set的核心区别
一、核心区别
特性 | List | Set |
---|---|---|
元素唯一性 | 允许重复元素 | 不允许重复元素 |
元素顺序 | 有序(按插入顺序或索引访问) | 无序(HashSet )或按特定顺序(TreeSet ) |
实现类 | ArrayList , LinkedList , Vector | HashSet , LinkedHashSet , TreeSet |
查找性能 | 按索引查找快(ArrayList 为 O(1)) | 查找元素快(HashSet 为 O(1)) |
适用场景 | 需要保留插入顺序或允许重复元素的场景 | 需要去重或快速查找元素的场景 |
二、详细对比
1. 元素唯一性
-
List:
-
允许存储重复元素。
-
示例:
List<String> list = new ArrayList<>(); list.add("Apple"); list.add("Banana"); list.add("Apple"); // 允许重复 System.out.println(list); // 输出: [Apple, Banana, Apple]
-
-
Set:
-
不允许存储重复元素。
-
示例:
Set<String> set = new HashSet<>(); set.add("Apple"); set.add("Banana"); set.add("Apple"); // 重复元素,不会被添加 System.out.println(set); // 输出: [Apple, Banana]
-
2. 元素顺序
-
List:
-
元素按插入顺序存储,可以通过索引访问。
-
示例:
List<String> list = new ArrayList<>(); list.add("Apple"); list.add("Banana"); list.add("Cherry"); System.out.println(list.get(1)); // 输出: Banana
-
-
Set:
-
元素无序(
HashSet
)或按特定顺序存储(TreeSet
按自然顺序,LinkedHashSet
按插入顺序)。 -
示例:
Set<String> hashSet = new HashSet<>(); hashSet.add("Apple"); hashSet.add("Banana"); hashSet.add("Cherry"); System.out.println(hashSet); // 输出: [Apple, Cherry, Banana](无序) Set<String> linkedHashSet = new LinkedHashSet<>(); linkedHashSet.add("Apple"); linkedHashSet.add("Banana"); linkedHashSet.add("Cherry"); System.out.println(linkedHashSet); // 输出: [Apple, Banana, Cherry](按插入顺序) Set<String> treeSet = new TreeSet<>(); treeSet.add("Banana"); treeSet.add("Apple"); treeSet.add("Cherry"); System.out.println(treeSet); // 输出: [Apple, Banana, Cherry](按自然顺序)
-
3. 实现类
-
List:
-
ArrayList
:基于动态数组实现,随机访问快,插入删除慢。 -
LinkedList
:基于双向链表实现,插入删除快,随机访问慢。 -
Vector
:线程安全的动态数组(已过时,推荐使用Collections.synchronizedList
或CopyOnWriteArrayList
)。
-
-
Set:
-
HashSet
:基于哈希表实现,元素无序。 -
LinkedHashSet
:基于哈希表和链表实现,元素按插入顺序排序。 -
TreeSet
:基于红黑树实现,元素按自然顺序或指定比较器排序。
-
4. 查找性能
-
List:
-
按索引查找快(
ArrayList
为 O(1))。 -
查找元素慢(需要遍历,时间复杂度为 O(n))。
-
示例:
List<String> list = new ArrayList<>(); list.add("Apple"); list.add("Banana"); list.add("Cherry"); System.out.println(list.get(1)); // 输出: Banana(O(1)) System.out.println(list.contains("Banana")); // 输出: true(O(n))
-
-
Set:
-
查找元素快(
HashSet
为 O(1))。 -
示例:
Set<String> set = new HashSet<>(); set.add("Apple"); set.add("Banana"); set.add("Cherry"); System.out.println(set.contains("Banana")); // 输出: true(O(1))
-
5. 适用场景
-
List:
-
需要保留插入顺序(如日志记录、用户操作记录)。
-
允许重复元素(如购物车中的商品)。
-
需要按索引访问元素(如随机访问列表中的元素)。
-
-
Set:
-
需要去重(如统计唯一用户 ID)。
-
需要快速查找元素(如黑名单检查)。
-
需要按特定顺序存储元素(如按字母顺序排序的单词列表)。
-
三、总结
特性 | List | Set |
---|---|---|
元素唯一性 | 允许重复 | 不允许重复 |
元素顺序 | 有序 | 无序或按特定顺序 |
查找性能 | 按索引快,查找元素慢 | 查找元素快 |
实现类 | ArrayList , LinkedList , Vector | HashSet , LinkedHashSet , TreeSet |
适用场景 | 保留顺序、允许重复、按索引访问 | 去重、快速查找、按特定顺序存储 |
根据具体需求选择合适的集合类型:
-
如果需要保留顺序或允许重复元素,使用 List。
-
如果需要去重或快速查找元素,使用 Set。