• 【数据结构】List、Set、Map的联系和区别(通俗易懂,清晰直观!!)


    目录

    List(列表):

    ArrayList

    LinkedList

    ArrayList和LinkedList的关系

    Set(集合):

    HashSet

    TreeSet

    HashSet和TreeSet的关系和区别

    Map(映射):

    HashMap

    TreeMap

    List、Set、Map这三个大类的关系和区别


         

       当涉及到数据集合时,List、Set和Map是常用的数据结构。它们之间有一些相似之处,同时也有一些区别。

    List(列表):

    • List 是一个有序的集合,允许重复元素。
    • 可以通过索引访问列表中的元素,索引从0开始。
    • List 通常实现为动态数组或链表的形式。
    • 常见的 List 实现包括 ArrayList 和 LinkedList。
    • 示例:[1, 2, 3, 2, 4]

    ArrayList

    • ArrayList 是一个基于动态数组的集合,它能够自动增长和缩小
    • 它允许快速随机访问任意位置的元素,因为它在内部使用数组来存储元素。
    • 数组可以被直接访问,所以 ArrayList 的随机访问非常快速
    • 在添加和删除时需要移动大量元素,效率较低。
    • 示例代码:
    1. import java.util.ArrayList;
    2. public class ArrayListExample {
    3. public static void main(String[] args) {
    4. ArrayList list = new ArrayList();
    5. list.add("Alice");
    6. list.add("Bob");
    7. list.add("Charlie");
    8. list.add("David");
    9. System.out.println("List size: " + list.size());
    10. for(String name : list) {
    11. System.out.println(name);
    12. }
    13. }
    14. }

    LinkedList

    • LinkedList 是一个基于链表的集合,每个元素都包含了一个指向下一个元素的引用。
    • 它不允许快速随机访问任意位置的元素,因为必须从头结点开始遍历链表才能到达目标元素。
    • 在添加和删除时无需移动元素,效率较高。
    • 链表的节点之间可以插入新的节点,构建复杂的数据结构。
    • 示例代码:
    1. import java.util.LinkedList;
    2. public class LinkedListExample {
    3. public static void main(String[] args) {
    4. LinkedList list = new LinkedList();
    5. list.add("Alice");
    6. list.add("Bob");
    7. list.add("Charlie");
    8. list.add("David");
    9. System.out.println("List size: " + list.size());
    10. for(String name : list) {
    11. System.out.println(name);
    12. }
    13. }
    14. }

    ArrayList和LinkedList的关系

    • ArrayList 和 LinkedList 都是 List 接口的实现类,它们都可以用于存储一组元素。
    • ArrayList 底层使用数组来存储元素,而 LinkedList 底层使用双向链表来存储元素。
    • ArrayList 支持快速随机访问任意位置的元素,但是在添加和删除时需要移动大量元素,效率较低。
    • LinkedList 不支持快速随机访问任意位置的元素,但是在添加和删除时无需移动元素,效率较高。
    • 在大多数情况下,ArrayList 的性能优于 LinkedList。但是,如果需要经常添加或删除元素,或者构建复杂的数据结构,那么选择 LinkedList 可能更好。

    Set(集合):

    • Set 是一个不允许重复元素的集合,保持元素的唯一性。
    • 元素在 Set 中没有特定的顺序。
    • Set 通常用于判断元素是否存在,或者去重操作。
    • 常见的 Set 实现包括 HashSet 和 TreeSet。
    • 示例:{1, 2, 3, 4}

    HashSet

    • HashSet 是基于哈希表实现的集合,它使用哈希函数来确定元素在集合中的存储位置。
    • HashSet 不保证元素的顺序,元素的存储顺序是不确定的。
    • HashSet 允许存储空值(null)。
    • HashSet 的插入、删除和查找操作都具有常数时间复杂度 O(1) 的性能。
    • 由于元素的存储位置是根据哈希值计算得到的,因此 HashSet 并不能按照元素的顺序进行遍历。
    • 简单使用示例:
    1. // HashSet 示例
    2. HashSet hashSet = new HashSet<>();
    3. // 添加元素
    4. hashSet.add("Apple");
    5. hashSet.add("Banana");
    6. hashSet.add("Orange");
    7. hashSet.add("Mango");
    8. hashSet.add("Apple"); // 重复元素不会被添加
    9. // 输出 HashSet
    10. System.out.println("HashSet: " + hashSet);
    11. // 输出结果为:HashSet: [Orange, Banana, Apple, Mango]
    12. // 元素的顺序是不确定的
    13. // 判断元素是否存在
    14. boolean containsApple = hashSet.contains("Apple");
    15. System.out.println("HashSet contains \"Apple\": " + containsApple);
    16. // 输出结果为:HashSet contains "Apple": true
    17. // 删除元素
    18. hashSet.remove("Banana");
    19. System.out.println("HashSet after removing \"Banana\": " + hashSet);
    20. // 输出结果为:HashSet after removing "Banana": [Orange, Apple, Mango]
    21. // 判断 HashSet 是否为空
    22. boolean isEmpty = hashSet.isEmpty();
    23. System.out.println("Is HashSet empty? " + isEmpty);
    24. // 输出结果为:Is HashSet empty? false
    25. // 获取 HashSet 的大小
    26. int size = hashSet.size();
    27. System.out.println("HashSet size: " + size);
    28. // 输出结果为:HashSet size: 3

    TreeSet

    • TreeSet 是基于红黑树(一种自平衡二叉搜索树)实现的集合,它可以对元素进行排序存储。
    • TreeSet 会对元素按照其自然顺序(或者根据指定的 Comparator 进行比较)进行排序。
    • TreeSet 不允许存储空值(null)。
    • TreeSet 的插入、删除和查找操作的时间复杂度取决于树的高度,通常为 O(logN),其中 N 为元素个数。
    • TreeSet 可以按照元素的顺序进行迭代遍历。
    • 简单的使用代码示例:
    1. // TreeSet 示例
    2. TreeSet treeSet = new TreeSet<>();
    3. // 添加元素
    4. treeSet.add("Apple");
    5. treeSet.add("Banana");
    6. treeSet.add("Orange");
    7. treeSet.add("Mango");
    8. treeSet.add("Apple"); // 重复元素不会被添加
    9. // 输出 TreeSet
    10. System.out.println("TreeSet: " + treeSet);
    11. // 输出结果为:TreeSet: [Apple, Banana, Mango, Orange]
    12. // 元素按照字母顺序进行排序存储
    13. // 获取第一个元素
    14. String firstElement = treeSet.first();
    15. System.out.println("First element in TreeSet: " + firstElement);
    16. // 输出结果为:First element in TreeSet: Apple
    17. // 获取最后一个元素
    18. String lastElement = treeSet.last();
    19. System.out.println("Last element in TreeSet: " + lastElement);
    20. // 输出结果为:Last element in TreeSet: Orange
    21. // 获取小于某个元素的最大元素
    22. String lowerElement = treeSet.lower("Banana");
    23. System.out.println("Element lower than \"Banana\": " + lowerElement);
    24. // 输出结果为:Element lower than "Banana": Apple
    25. // 获取大于某个元素的最小元素
    26. String higherElement = treeSet.higher("Banana");
    27. System.out.println("Element higher than \"Banana\": " + higherElement);
    28. // 输出结果为:Element higher than "Banana": Mango
    29. // 删除元素
    30. treeSet.remove("Banana");
    31. System.out.println("TreeSet after removing \"Banana\": " + treeSet);
    32. // 输出结果为:TreeSet after removing "Banana": [Apple, Mango, Orange]
    33. // 清空 TreeSet
    34. treeSet.clear();
    35. System.out.println("TreeSet after clearing: " + treeSet);
    36. // 输出结果为:TreeSet after clearing: []

    HashSet和TreeSet的关系和区别

    • HashSet 和 TreeSet 都实现了 Set 接口,因此它们都不允许存储重复元素。
    • HashSet 是无序的,而 TreeSet 是有序的。
    • HashSet 的插入和查找操作性能更好,因为它使用哈希表进行元素存储;而 TreeSet 提供了有序的存储和检索操作,但相对来说性能更差。
    • 在需要快速插入、删除和查找元素,并不关心元素的顺序时,可以选择使用 HashSet。而在需要有序存储和遍历元素的场景中,可以选择使用 TreeSet。

    Map(映射):

    • Map 是一种键值对的集合,每个键都是唯一的。
    • 可以通过键来访问、插入或删除对应的值。
    • Map 中的键-值对没有特定的顺序。
    • 常见的 Map 实现包括 HashMap 和 TreeMap。
    • 示例:{ "key1" -> "value1", "key2" -> "value2", "key3" -> "value3" }

    HashMap

            HashMap 是基于哈希表实现的,它使用键的哈希值来进行存储和检索操作。它的特点是存储顺序不确定,不保证元素的顺序。HashMap 允许使用 null 作为键和值,并且允许存在重复的值,但不允许存在重复的键。

    基本使用示例:

    1. // HashMap 示例
    2. HashMap hashMap = new HashMap<>();
    3. // 添加键值对
    4. hashMap.put(3, "Apple");
    5. hashMap.put(1, "Banana");
    6. hashMap.put(2, "Orange");
    7. hashMap.put(4, "Mango");
    8. hashMap.put(1, "Grape"); // 重复的键会覆盖旧的值
    9. // 输出 HashMap
    10. System.out.println("HashMap: " + hashMap);
    11. // 输出结果为:HashMap: {1=Grape, 2=Orange, 3=Apple, 4=Mango}
    12. // 元素的顺序是不确定的
    13. // 获取值
    14. String value = hashMap.get(3);
    15. System.out.println("Value for key 3: " + value);
    16. // 输出结果为:Value for key 3: Apple
    17. // 判断是否包含键
    18. boolean containsKey = hashMap.containsKey(2);
    19. System.out.println("HashMap contains key 2: " + containsKey);
    20. // 输出结果为:HashMap contains key 2: true
    21. // 删除键值对
    22. hashMap.remove(1);
    23. System.out.println("HashMap after removing key 1: " + hashMap);
    24. // 输出结果为:HashMap after removing key 1: {2=Orange, 3=Apple, 4=Mango}
    25. // 判断 HashMap 是否为空
    26. boolean isEmpty = hashMap.isEmpty();
    27. System.out.println("Is HashMap empty? " + isEmpty);
    28. // 输出结果为:Is HashMap empty? false
    29. // 获取 HashMap 的大小
    30. int size = hashMap.size();
    31. System.out.println("HashMap size: " + size);
    32. // 输出结果为:HashMap size: 3

    TreeMap

            TreeMap 是基于红黑树实现的,它会根据键的自然顺序或者自定义比较器的顺序来进行存储和检索操作。TreeMap 内部会对键进行排序,并且提供了按照键的自然顺序或者自定义比较器顺序的迭代器。TreeMap 不允许使用 null 作为键,但可以使用 null 作为值。TreeMap 中的键是有序的,因此迭代时会按照键的顺序进行遍历。

    使用的简单示例:

    1. // TreeMap 示例
    2. TreeMap treeMap = new TreeMap<>();
    3. // 添加键值对
    4. treeMap.put(3, "Apple");
    5. treeMap.put(1, "Banana");
    6. treeMap.put(2, "Orange");
    7. treeMap.put(4, "Mango");
    8. treeMap.put(1, "Grape"); // 重复的键会覆盖旧的值
    9. // 输出 TreeMap
    10. System.out.println("TreeMap: " + treeMap);
    11. // 输出结果为:TreeMap: {1=Grape, 2=Orange, 3=Apple, 4=Mango}
    12. // 元素按照键的自然顺序进行排序存储
    13. // 获取第一个键值对
    14. Map.Entry firstEntry = treeMap.firstEntry();
    15. System.out.println("First entry in TreeMap: " + firstEntry);
    16. // 输出结果为:First entry in TreeMap: 1=Grape
    17. // 获取最后一个键值对
    18. Map.Entry lastEntry = treeMap.lastEntry();
    19. System.out.println("Last entry in TreeMap: " + lastEntry);
    20. // 输出结果为:Last entry in TreeMap: 4=Mango
    21. // 获取小于某个键的最大键值对
    22. Map.Entry lowerEntry = treeMap.lowerEntry(3);
    23. System.out.println("Entry with key lower than 3: " + lowerEntry);
    24. // 输出结果为:Entry with key lower than 3: 2=Orange
    25. // 获取大于某个键的最小键值对
    26. Map.Entry higherEntry = treeMap.higherEntry(3);
    27. System.out.println("Entry with key higher than 3: " + higherEntry);
    28. // 输出结果为:Entry with key higher than 3: 4=Mango
    29. // 删除键值对
    30. treeMap.remove(1);
    31. System.out.println("TreeMap after removing key 1: " + treeMap);
    32. // 输出结果为:TreeMap after removing key 1: {2=Orange, 3=Apple, 4=Mango}
    33. // 清空 TreeMap
    34. treeMap.clear();
    35. System.out.println("TreeMap after clearing: " + treeMap);
    36. // 输出结果为:TreeMap after clearing: {}

    List、Set、Map这三个大类的关系和区别

    • List 和 Set 都是集合,都用于存储一组元素。List 是有序的、允许重复元素的集合;Set 是无序的、不允许重复元素的集合。
    • Map 是键值对的集合,通过键来唯一标识和访问值,键是唯一的。
    • List 和 Set 可以使用迭代器遍历所有元素,而 Map 可以使用键来遍历所有键值对。
    • List 可以通过索引获取元素,而 Set 和 Map 不能直接通过索引访问元素。
    • List 的主要实现类有 ArrayList(基于动态数组)和 LinkedList(基于链表),而 Set 和 Map 的主要实现类有 HashSet(基于哈希表)和 TreeSet(基于红黑树)。
  • 相关阅读:
    Vertica常用的sql
    视频转换器 AnyMP4 Video Converter Ultimate v8.5.52 x64
    Fastnet,三步完成高性能的网络开发
    MySQL之InnoDB引擎(六)
    Leecode33:二叉搜索树的后续遍历序列
    ProGuard使用简介
    100天精通Python(可视化篇)——第101天:Pyecharts绘制多种炫酷仪表盘图参数说明+代码实战
    4.2.2-测试应用程序平台配置
    Web学习笔记-中期项目(拳皇)
    VUE3-工作笔记05
  • 原文地址:https://blog.csdn.net/miles067/article/details/132789024