• Java学习笔记——Collection之Set


    目录

    一、Set相关概念

    二、HashSet

    LinkedHashSet

    三、EnumSet

    四、TreeSet

    五、代码

    1、HashSet

    2、TreeSet

    一、Set相关概念

    Set:无序不可重复的集合,只能根据元素本身来访问

    Set接口常用的实现类有:HashSet、LinkedHashSet、TreeSet

    关于常见的类方法,总结如下:

    • HashSet
    1. 底层其实是包装了一个HashMap实现的
    2. 底层数据结构是数组+链表 + 红黑树
    3. 具有比较好的读取和查找性能, 可以有null 值
    4. 通过equalsHashCode来判断两个元素是否相等
    5. 非线程安全
    • LinkedHashSet
    1. 继承HashSet,本质是LinkedHashMap实现
    2. 底层数据结构由哈希表(是一个元素为链表的数组)和双向链表组成。
    3. 有序的,根据HashCode的值来决定元素的存储位置,同时使用一个链表来维护元素的插入顺序
    4. 非线程安全
    5. 可以有null 值
    • TreeSet
    • 底层是用TreeMap实现的,本质上是一个红黑树原理
    • 排序分两种:自然排序和自定义排序
    • 不能有null值,可通过重写Comparable接口有null值

    二、HashSet

    1. HashSet是Set接口的实现类,由哈希表支持,它不保证集合的迭代顺序;
    2. Hashset允许null元素;
    3. HashSet 是无序的,即不会记录插入的顺序;
    4. HashSet 不是线程安全的, 如果多个线程尝试同时修改 HashSet,则最终结果是不确定的。 您必须在多线程访问时显式同步对 HashSet 的并发访问;

    代码实例

    1. // 初始化
    2. HashSet language = new HashSet<>();
    3. // 添加元素
    4. System.out.println("------add()------");
    5. language.add("Java");
    6. language.add("Python");
    7. language.add("PHP");
    8. language.add("C++");
    9. System.out.println(language);
    10. language.add("Python");
    11. System.out.println("重复的元素不添加! " + language);
    12. // 包含
    13. System.out.println("------contains()------");
    14. System.out.println("contains(): " + language.contains("Java"));
    15. System.out.println("contains(): " + language.contains("C"));
    16. // 删除元素
    17. System.out.println("------remove()------");
    18. language.remove("C++");
    19. System.out.println(language);
    20. // for-each实现迭代
    21. System.out.println("------元素的迭代------");
    22. for (String l: language){
    23. System.out.println(l);
    24. }
    1. ------add()------
    2. [Java, C++, PHP, Python]
    3. 重复的元素不添加! [Java, C++, PHP, Python]
    4. ------contains()------
    5. contains(): true
    6. contains(): false
    7. ------remove()------
    8. [Java, PHP, Python]
    9. ------元素的迭代------
    10. Java
    11. PHP
    12. Python

    LinkedHashSet

    • LinkedHashSet是HashSet的子类;
    • LinkedHashSet底层是一个LinkedHashMap,底层维护了一个 数组+双向链表;
    • LinkedHashSet 加入和取出元素的顺序一致;
    • LinkedHashSet不是线程安全的,若多线程同时访问LinkedHashSet必须加锁,或通过使用Collections.SynchronizedSet;

    三、EnumSet

    EnumSet的用法请看Java学习笔记——枚举_柠檬不甜会酸的博客-CSDN博客

    四、TreeSet

    • TreeSet也是基于Map来实现,其底层结构为红黑树(特殊的二叉查找树);
    • TreeSet具有排序功能,分为自然排序(123456)和自定义排序两类,默认是自然排序;
    • TreeSet 继承于AbstractSet,所以它是一个Set集合,具有Set的属性和方法。
    • TreeSet 实现了NavigableSet接口,意味着它支持一系列的导航方法。比如查找与指定目标最匹配项。
    • 对插入的元素进行排序,是一个有序的集合(主要与HashSet的区别);
    • 允许插入Null值;
    • 不允许插入重复元素;
    • TreeSet是非线程安全的。

     (1)TreeSet的创建

    1. // TreeSet
    2. TreeSet treeSet = new TreeSet<>();
    3. System.out.println("TreeSet初始化容量的大小: " + treeSet.size());
    TreeSet初始化容量的大小: 0

    (2)添加元素

    1. // 添加元素
    2. treeSet.add(5);
    3. treeSet.add(10);
    4. treeSet.add(2);
    5. treeSet.add(-5);
    6. treeSet.add(3);
    7. treeSet.add(12);
    8. treeSet.add(100);
    9. treeSet.add(88);
    10. treeSet.add(99);
    11. System.out.println("------add()------");
    12. System.out.println("TreeSet容量大小: " + treeSet.size());
    13. System.out.println("TreeSet元素顺序为:" + treeSet.toString());
    1. ------add()------
    2. TreeSet容量大小: 9
    3. TreeSet元素顺序为:[-5, 2, 3, 5, 10, 12, 88, 99, 100]

    (3)删除元素

    1. // 删除元素
    2. treeSet.remove(-5);
    3. System.out.println("------remove()------");
    4. System.out.println("TreeSet元素顺序为:" + treeSet.toString());
    5. int first = treeSet.pollFirst();
    6. int last = treeSet.pollLast();
    7. System.out.println("删除并返回第一个元素:如果set集合不存在元素,则返回null:" + first);
    8. System.out.println("删除并返回最后一个元素:如果set集合不存在元素,则返回null:" + last);
    9. System.out.println("TreeSet元素顺序为:" + treeSet.toString());
    1. ------remove()------
    2. TreeSet元素顺序为:[2, 3, 5, 10, 12, 88, 99, 100]
    3. 删除并返回第一个元素:如果set集合不存在元素,则返回null2
    4. 删除并返回最后一个元素:如果set集合不存在元素,则返回null100
    5. TreeSet元素顺序为:[3, 5, 10, 12, 88, 99]

    (4)遍历

    1. // 遍历
    2. System.out.println("------for循环遍历------");
    3. for (int n: treeSet){
    4. System.out.println(n);
    5. }
    6. System.out.println("------升序------");
    7. Iterator treeAsc = treeSet.iterator();
    8. while (treeAsc.hasNext()){
    9. int tmp = treeAsc.next();
    10. System.out.println("升序: " + tmp);
    11. }
    12. System.out.println("------降序------");
    13. Iterator treeDec = treeSet.descendingIterator();
    14. while (treeDec.hasNext()){
    15. int tmp = treeDec.next();
    16. System.out.println("降序: " + tmp);
    17. }
    1. ------for循环遍历------
    2. 3
    3. 5
    4. 10
    5. 12
    6. 88
    7. 99
    8. ------升序------
    9. 升序: 3
    10. 升序: 5
    11. 升序: 10
    12. 升序: 12
    13. 升序: 88
    14. 升序: 99
    15. ------降序------
    16. 降序: 99
    17. 降序: 88
    18. 降序: 12
    19. 降序: 10
    20. 降序: 5
    21. 降序: 3

    (5)访问

    1. // 访问
    2. System.out.println("------访问------");
    3. System.out.println("头部结点: " + treeSet.first());
    4. System.out.println("尾部结点: " + treeSet.last());
    5. System.out.println("获取指定元素之前的所有元素集合:(不包含指定元素): " + treeSet.headSet(12));
    6. System.out.println("获取指定元素之后的所有元素集合:(包含指定元素): " + treeSet.tailSet(12));
    7. System.out.println("获取给定元素之间的集合:(包含头,不包含尾): " + treeSet.subSet(0, 12));
    1. ------访问------
    2. 头部结点: 3
    3. 尾部结点: 99
    4. 获取指定元素之前的所有元素集合:(不包含指定元素): [3, 5, 10]
    5. 获取指定元素之后的所有元素集合:(包含指定元素): [12, 88, 99]
    6. 获取给定元素之间的集合:(包含头,不包含尾): [3, 5, 10]

    (6)判断

    1. // 判断
    2. System.out.println("------判断------");
    3. System.out.println("treeSet是否为空: " + treeSet.isEmpty());
    4. System.out.println("treeSet是否包含12: " + treeSet.contains(12));
    1. ------判断------
    2. treeSet是否为空: false
    3. treeSet是否包含12: true

    五、代码

    1、HashSet

    1. import java.util.HashSet;
    2. public class Day30 {
    3. public static void main(String[] args){
    4. // 初始化
    5. HashSet language = new HashSet<>();
    6. // 添加元素
    7. System.out.println("------add()------");
    8. language.add("Java");
    9. language.add("Python");
    10. language.add("PHP");
    11. language.add("C++");
    12. System.out.println(language);
    13. language.add("Python");
    14. System.out.println("重复的元素不添加! " + language);
    15. // 包含
    16. System.out.println("------contains()------");
    17. System.out.println("contains(): " + language.contains("Java"));
    18. System.out.println("contains(): " + language.contains("C"));
    19. // 删除元素
    20. System.out.println("------remove()------");
    21. language.remove("C++");
    22. System.out.println(language);
    23. // for-each实现迭代
    24. System.out.println("------元素的迭代------");
    25. for (String l: language){
    26. System.out.println(l);
    27. }
    28. }
    29. }

    2、TreeSet

    1. import java.util.Iterator;
    2. import java.util.TreeSet;
    3. public class Day31 {
    4. public static void main(String[] args){
    5. // TreeSet
    6. TreeSet treeSet = new TreeSet<>();
    7. System.out.println("TreeSet初始化容量的大小: " + treeSet.size());
    8. // 添加元素
    9. treeSet.add(5);
    10. treeSet.add(10);
    11. treeSet.add(2);
    12. treeSet.add(-5);
    13. treeSet.add(3);
    14. treeSet.add(12);
    15. treeSet.add(100);
    16. treeSet.add(88);
    17. treeSet.add(99);
    18. System.out.println("------add()------");
    19. System.out.println("TreeSet容量大小: " + treeSet.size());
    20. System.out.println("TreeSet元素顺序为:" + treeSet.toString());
    21. // 删除元素
    22. treeSet.remove(-5);
    23. System.out.println("------remove()------");
    24. System.out.println("TreeSet元素顺序为:" + treeSet.toString());
    25. int first = treeSet.pollFirst();
    26. int last = treeSet.pollLast();
    27. System.out.println("删除并返回第一个元素:如果set集合不存在元素,则返回null:" + first);
    28. System.out.println("删除并返回最后一个元素:如果set集合不存在元素,则返回null:" + last);
    29. System.out.println("TreeSet元素顺序为:" + treeSet.toString());
    30. // 遍历
    31. System.out.println("------for循环遍历------");
    32. for (int n: treeSet){
    33. System.out.println(n);
    34. }
    35. System.out.println("------升序------");
    36. Iterator treeAsc = treeSet.iterator();
    37. while (treeAsc.hasNext()){
    38. int tmp = treeAsc.next();
    39. System.out.println("升序: " + tmp);
    40. }
    41. System.out.println("------降序------");
    42. Iterator treeDec = treeSet.descendingIterator();
    43. while (treeDec.hasNext()){
    44. int tmp = treeDec.next();
    45. System.out.println("降序: " + tmp);
    46. }
    47. // 访问
    48. System.out.println("------访问------");
    49. System.out.println("头部结点: " + treeSet.first());
    50. System.out.println("尾部结点: " + treeSet.last());
    51. System.out.println("获取指定元素之前的所有元素集合:(不包含指定元素): " + treeSet.headSet(12));
    52. System.out.println("获取指定元素之后的所有元素集合:(包含指定元素): " + treeSet.tailSet(12));
    53. System.out.println("获取给定元素之间的集合:(包含头,不包含尾): " + treeSet.subSet(0, 12));
    54. // 判断
    55. System.out.println("------判断------");
    56. System.out.println("treeSet是否为空: " + treeSet.isEmpty());
    57. System.out.println("treeSet是否包含12: " + treeSet.contains(12));
    58. }
    59. }
  • 相关阅读:
    Toronto Research Chemicals 杀菌抗生素丨磷霉素-蔗糖醚二钠盐
    Java_Servlet处理请求流程
    linux 网络接口的子接口的配置
    Node.js(7)-node的http模块
    【神经网络】Python基于numpy灵活定义神经网络结构的方法
    C语言实现printf同行输出(刷新显示)
    C++11之防止类型收窄(列表初始化)
    python用socket实现简易局域网UDP组播屏幕分享
    Java毕设项目——人才招聘网站(java+SpringBoot+Maven+Mysql+Jsp)
    设计模式-代理模式
  • 原文地址:https://blog.csdn.net/weixin_45666660/article/details/126035213