List 和 Set 的区别

发布于:2025-03-22 ⋅ 阅读:(13) ⋅ 点赞:(0)

📌 List 和 Set 的区别

在 Java 中,ListSet 都是 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 适用于存储无序、不可重复的数据,查询性能较优。