• Java集合之Set集合


    Set集合怎么使用呢?


    目录

    Set接口

    特点:

    遍历:

    扩容:

    实现:

    1.HashSet

     特点:

    代码运用:

    2.TreeSet

    特点:

    代码运用:


    Set接口

    特点:

              Set:无序,不重复(无序:存入和拿出来的顺序不同所以不能使用下标)

    遍历:

            foreach迭代器

    扩容:

            初始容量16,负载因子0.75,扩容增量1倍

    实现:

    对于 HashSet 而言,它是基于 HashMap 实现的,HashSet 底层使用 HashMap 来保存所有元素,因此 HashSet 的实现比较简单,相关 HashSet 的操作,基本上都是直接调用底层 HashMap 的相关方法来完成,我们应该为保存到 HashSet 中的对象覆盖 hashCode() 和 equals()

    已知实现接口有:

    Serializable, Cloneable, Iterable<E>, Collection<E>, Set<E>

    已知子类:

    JobStateReasons, LinkedHashSet

    1.HashSet

     特点:

    • 它存储唯一元素允许空值        依据对象的hashcode来确定该元素是否存在
    • 由HashMap支持
    • 不保持插入顺序
    • 非线程安全
    • 性能参数:初始容量,负载因子       默认值: 初始容量16,负载因子0.75
    •                                                           示例:new HashSet<>(20, 0.5f);
    • 思考:

               1. 如何给ArrayList集合去重

               2. set有ArrayList中存在的通过下标删除,或foreach循环删除时的问题吗? 为什么

               3. set是否存在List删除,传入整数需要区分是基本型还是对象型的问题,【例如:list.remove(2)】,为什么? 

               4. HashSet是如何实现的?

    代码运用:

    如何把ArrayList中重复的元素去掉(去重),方法有很多,大佬们可以自己试着写几个,这里提供一个比较简单快速的方法:使用HashSet去重🍭🍭

    1. public class SetDemo {
    2. private List<Integer> list = new ArrayList<>();
    3. @BeforeAll
    4. public void setup() {
    5. set.add(1);
    6. set.add(1);
    7. set.add(2);
    8. set.add(2);
    9. set.add(3);
    10. set.add(3);
    11. }
    12. @Test
    13. public void test01() {
    14. List<Integer> tmp = new ArrayList<>(new HashSet<Integer>(list));
    15. System.out.println(tmp);
    16. }
    17. }

    输出结果是123(ArrayList是可以存放重复元素的,但是这里使用了HashSet去重)

    1、新建一个Set集合并放入元素🍭🍭🍭

    1. public class SetDemo {
    2. private Set<Integer> set = new HashSet<>();
    3. @BeforeAll
    4. public void setup() {
    5. set.add(1);
    6. set.add(1);
    7. set.add(2);
    8. set.add(4);
    9. set.add(5);
    10. set.add(3);
    11. }
    12. }

    2、可以使用下面两种方法遍历其中的元素,由于HashSet中只能存储不重复的对象,所以输出时会自动把重复的元素去重🍬🍬🍬

    1. @Test
    2. public void test02() {
    3. for(Integer e: set) {
    4. System.out.println(e);
    5. }
    6. }
    7. //使用迭代器
    8. @Test
    9. public void test03() {
    10. Iterator<Integer> it = set.iterator();
    11. while(it.hasNext()) {
    12. System.out.println(it.next());
    13. }
    14. }

    3、set.remove(i)中传入的是元素,这是由于HashSet不保证插入顺序,没有下标概念,所以只能传入元素🍡🍡🍡

    1. @Test
    2. public void test05() {
    3. set.remove(3);
    4. System.out.println(set);
    5. }

    删除的是第一步里面Set集合里面的元素3,输出的是1245 


    2.TreeSet

    特点:

    • 是一个包含有序的且没有重复元素的集合
    • 作用是提供有序的Set集合,自然排序或者根据提供的Comparator进行排序
    • TreeSet是基于TreeMap实现的

    示例:

            测试数据

            1. 默认自然排序

            2. 自定义比较器:1. 通过构造函数传入比较器      2. 实现排序接口

    代码运用:

    创建一个学生类并实现编比较器接口🍧🍧🍧

    1. public class Student implements Comparable<Student>{
    2. private Integer sid;
    3. private String sname;
    4. private int age;
    5. public Student(Integer sid, String sname, int age) {
    6. super();
    7. this.sid = sid;
    8. this.sname = sname;
    9. this.age = age;
    10. }
    11. public Integer getSid() {
    12. return sid;
    13. }
    14. public void setSid(Integer sid) {
    15. this.sid = sid;
    16. }
    17. public String getSname() {
    18. return sname;
    19. }
    20. public void setSname(String sname) {
    21. this.sname = sname;
    22. }
    23. public int getAge() {
    24. return age;
    25. }
    26. public void setAge(int age) {
    27. this.age = age;
    28. }
    29. }

    还需要在这个学生类中实现hashCodeequals方法:

    1. /*
    2. *hashCode可以将学号名字努力转成唯一的数字,相对于身份证
    3. */
    4. @Override
    5. public int hashCode() {
    6. final int prime = 31;
    7. int result = 1;
    8. result = prime * result + age;
    9. result = prime * result + ((sid == null) ? 0 : sid.hashCode());
    10. result = prime * result + ((sname == null) ? 0 : sname.hashCode());
    11. return result;
    12. }
    13. @Override
    14. public boolean equals(Object obj) {
    15. if (this == obj)
    16. return true;
    17. if (obj == null)
    18. return false;
    19. if (getClass() != obj.getClass())
    20. return false;
    21. Student other = (Student) obj;
    22. if (age != other.age)
    23. return false;
    24. if (sid == null) {
    25. if (other.sid != null)
    26. return false;
    27. } else if (!sid.equals(other.sid))
    28. return false;
    29. if (sname == null) {
    30. if (other.sname != null)
    31. return false;
    32. } else if (!sname.equals(other.sname))
    33. return false;
    34. return true;//学号名字年龄都相等才是同一个学生
    35. }
    36. @Override
    37. public String toString() {
    38. return "Student [sid=" + sid + ", sname=" + sname + ", age=" + age + "]";
    39. }
    40. /**
    41. * 实现Comparable<Student>接口后需要重写的方法
    42. * 根据年龄排序,年龄相同则比较学号,默认是升序
    43. */
    44. @Override
    45. public int compareTo(Student o) {
    46. if(this.getAge()-o.getAge()==0) {
    47. return this.getSid()-o.getSid();
    48. }
    49. return this.getAge() - o.getAge();
    50. }

    然后再使用ThreeSet

    1. @Test
    2. public void test04() {
    3. TreeSet<Student> stu = new TreeSet<>();
    4. stu.add(new Student(1,"zs", 18));
    5. stu.add(new Student(1,"zs", 18));
    6. stu.add(new Student(2,"ls", 19));
    7. stu.add(new Student(4,"lihao", 10));
    8. stu.add(new Student(7,"lihao", 18));
    9. stu.add(new Student(5,"zengfanyan", 20));
    10. stu.add(new Student(3,"we", 30));
    11. for(Student s: stu) {
    12. System.out.println(s);
    13. }
    14. }

    运行输出结果:

     

     


    感谢收看鸭~

  • 相关阅读:
    我的Vue组件化开发首个项目todolist
    C++设计模式-创建型设计模式:抽象工厂
    为什么红黑树比AVL树效率高?
    Operator3-设计一个operator
    【无标题】
    HackTheBox-Starting Point--Tier 0---Preignition
    centos7安装nginx
    uniapp 短信监听(验证码)插件 Ba-Sms
    史上最全 JVM 性能调优:线程 + 子系统 + 类加载 + 内存分配 + 垃圾回收(内附最全学习笔记),不得不服,面试官也问不出毛病
    用正则表达式处理文本--1
  • 原文地址:https://blog.csdn.net/m0_64043477/article/details/125497474