• Set集合


    目录

    一、特点

    二、遍历

    三、扩容

    四、实现

    HashSet

    TreeSet

    自定义比较器

    通过构造函数传入比较器

     实现排序接口


    一、特点

    特点:无序,不重复

    如何去重❓

    先将包含重复元素的list构造出一个HashSet,再通过HashSet构造出一个ArrayList

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

    效果图如下:

    二、遍历

    foreach,迭代器

    1. private Set<Integer>set=new HashSet<>();
    2. @Before
    3. public void setup() {
    4. set.add(1);
    5. set.add(2);
    6. set.add(2);
    7. set.add(3);
    8. set.add(4);
    9. set.add(5);
    10. set.add(6);
    11. set.add(7);
    12. }
    13. /**
    14. * foreach遍历
    15. */
    16. @Test
    17. public void test02() {
    18. for (Integer e : set) {
    19. System.out.println(e);
    20. }
    21. }
    22. /**
    23. * 迭代器
    24. */
    25. @Test
    26. public void test03() {
    27. Iterator<Integer> it = set.iterator();
    28. while(it.hasNext()) {
    29. System.out.println(it.next());
    30. }
    31. }

    效果图如下:

    三、扩容

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

    四、实现

    • HashSet

    它存储唯一元素并允许空值,依据对象的hashcode来确定该元素是否存在

    示例:

    首先建立一个Student的实体类

    1. package com.zking.set;
    2. public class Student {
    3. private Integer sid;
    4. private String sname;
    5. private Integer sage;
    6. public Integer getSid() {
    7. return sid;
    8. }
    9. public void setSid(Integer sid) {
    10. this.sid = sid;
    11. }
    12. public String getSname() {
    13. return sname;
    14. }
    15. public void setSname(String sname) {
    16. this.sname = sname;
    17. }
    18. public Integer getSage() {
    19. return sage;
    20. }
    21. public void setSage(Integer sage) {
    22. this.sage = sage;
    23. }
    24. public Student(Integer sid, String sname, Integer sage) {
    25. super();
    26. this.sid = sid;
    27. this.sname = sname;
    28. this.sage = sage;
    29. }
    30. public Student() {
    31. super();
    32. }
    33. @Override
    34. public String toString() {
    35. return "Student [sid=" + sid + ", sname=" + sname + ", sage=" + sage + "]";
    36. }
    37. }

    测试方法

    1. public void test04() {
    2. Set<Student>stu=new HashSet<>();
    3. stu.add(new Student(1,"苡桉",18));
    4. stu.add(new Student(1,"苡桉",18));
    5. stu.add(new Student(2,"千帆",19));
    6. stu.add(new Student(3,"鼠标",17));
    7. stu.add(new Student(4,"耳机",22));
    8. stu.add(new Student(5,"安楠",30));
    9. for (Student s : stu) {
    10. System.out.println(s);
    11. }
    12. }

    运行结果:发现并没有去重

     在实体类里重写hascode以及equals方法后

    1. @Override
    2. public int hashCode() {
    3. final int prime = 31;
    4. int result = 1;
    5. result = prime * result + ((sage == null) ? 0 : sage.hashCode());
    6. result = prime * result + ((sid == null) ? 0 : sid.hashCode());
    7. result = prime * result + ((sname == null) ? 0 : sname.hashCode());
    8. return result;
    9. }
    10. @Override
    11. public boolean equals(Object obj) {
    12. if (this == obj)
    13. return true;
    14. if (obj == null)
    15. return false;
    16. if (getClass() != obj.getClass())
    17. return false;
    18. Student other = (Student) obj;
    19. if (sage == null) {
    20. if (other.sage != null)
    21. return false;
    22. } else if (!sage.equals(other.sage))
    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. }

    效果图如下:去重成功 

    注意:HashSet不保持插入顺序,非线程安全

    性能参数:初始容量,负载因子

    1. 默认值: 初始容量16,负载因子0.75
    2. 示例:new HashSet<>(20, 0.5f);

    set删除(删除元素)

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

    效果图如下: 

    • TreeSet

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

    示例:如何根据年龄排序(从大到小)❓

    1. public void test04() {
    2. //自定义比较器
    3. TreeSet<Student>stu=new TreeSet<>(new Comparator<Student>() {
    4. @Override
    5. public int compare(Student o1, Student o2) {
    6. return o2.getSage()-o1.getSage();
    7. }
    8. });
    9. stu.add(new Student(1,"苡桉",18));
    10. stu.add(new Student(1,"苡桉",18));
    11. stu.add(new Student(2,"千帆",19));
    12. stu.add(new Student(3,"鼠标",17));
    13. stu.add(new Student(4,"耳机",22));
    14. stu.add(new Student(5,"安楠",30));
    15. for (Student s : stu) {
    16. System.out.println(s);
    17. }
    18. }

    效果图如下:

    删除对象

    自定义比较器

    • 通过构造函数传入比较器

    1. public void test04() {
    2. TreeSet<Student>stu=new TreeSet<>(new Comparator<Student>() {
    3. @Override
    4. public int compare(Student o1, Student o2) {
    5. return o2.getSid()-o1.getSid();
    6. }
    7. });
    8. stu.add(new Student(1,"苡桉",18));
    9. stu.add(new Student(1,"苡桉",18));
    10. stu.add(new Student(2,"千帆",19));
    11. stu.add(new Student(3,"鼠标",17));
    12. stu.add(new Student(7,"鼠标",18));
    13. stu.add(new Student(4,"耳机",22));
    14. stu.add(new Student(5,"安楠",30));
    15. stu.remove(new Student(3,"鼠标",17));
    16. for (Student s : stu) {
    17. System.out.println(s);
    18. }
    19. }

    效果图如下: 

    •  实现排序接口

    1. package com.zking.set;
    2. public class Student implements Comparable<Student>{
    3. private Integer sid;
    4. private String sname;
    5. private Integer sage;
    6. public Integer getSid() {
    7. return sid;
    8. }
    9. public void setSid(Integer sid) {
    10. this.sid = sid;
    11. }
    12. public String getSname() {
    13. return sname;
    14. }
    15. public void setSname(String sname) {
    16. this.sname = sname;
    17. }
    18. public Integer getSage() {
    19. return sage;
    20. }
    21. public void setSage(Integer sage) {
    22. this.sage = sage;
    23. }
    24. public Student(Integer sid, String sname, Integer sage) {
    25. super();
    26. this.sid = sid;
    27. this.sname = sname;
    28. this.sage = sage;
    29. }
    30. public Student() {
    31. super();
    32. }
    33. @Override
    34. public String toString() {
    35. return "Student [sid=" + sid + ", sname=" + sname + ", sage=" + sage + "]";
    36. }
    37. @Override
    38. public int hashCode() {
    39. final int prime = 31;
    40. int result = 1;
    41. result = prime * result + ((sage == null) ? 0 : sage.hashCode());
    42. result = prime * result + ((sid == null) ? 0 : sid.hashCode());
    43. result = prime * result + ((sname == null) ? 0 : sname.hashCode());
    44. return result;
    45. }
    46. @Override
    47. public boolean equals(Object obj) {
    48. if (this == obj)
    49. return true;
    50. if (obj == null)
    51. return false;
    52. if (getClass() != obj.getClass())
    53. return false;
    54. Student other = (Student) obj;
    55. if (sage == null) {
    56. if (other.sage != null)
    57. return false;
    58. } else if (!sage.equals(other.sage))
    59. return false;
    60. if (sid == null) {
    61. if (other.sid != null)
    62. return false;
    63. } else if (!sid.equals(other.sid))
    64. return false;
    65. if (sname == null) {
    66. if (other.sname != null)
    67. return false;
    68. } else if (!sname.equals(other.sname))
    69. return false;
    70. return true;
    71. }
    72. @Override
    73. public int compareTo(Student o) {
    74. // TODO Auto-generated method stub
    75. return this.getSid()-o.getSid();
    76. }
    77. }

    注意:在使用比较器进行删除时要注意比较器中的字段  若删除的数据中有重复的元素  而这个元素如果与比较器的字段一样 那么可能会出现删除错误。 因为比较器会根据你设定的字段排序,如果出现重复会自动进行去重。

    1. public void test04() {
    2. TreeSet<Student>stu=new TreeSet<>(new Comparator<Student>() {
    3. @Override
    4. public int compare(Student o1, Student o2) {
    5. return o2.getSage()-o1.getSage();
    6. }
    7. });
    8. stu.add(new Student(1,"苡桉",18));
    9. stu.add(new Student(1,"苡桉",18));
    10. stu.add(new Student(2,"千帆",19));
    11. stu.add(new Student(3,"鼠标",17));
    12. stu.add(new Student(7,"鼠标",18));
    13. stu.add(new Student(4,"耳机",22));
    14. stu.add(new Student(5,"安楠",30));
    15. stu.remove(new Student(3,"鼠标",17));
    16. for (Student s : stu) {
    17. System.out.println(s);
    18. }
    19. }

    效果图入下:会发现想删除的的是 Student(3,"鼠标",17),却把Student(7,"鼠标",18)也删了

     解决方案如下:

    1. public void test04() {
    2. TreeSet<Student>stu=new TreeSet<>(new Comparator<Student>() {
    3. @Override
    4. public int compare(Student o1, Student o2) {
    5. if(o1.getSage()-o2.getSage()==0) {
    6. return o1.getSid()-o2.getSid();
    7. }
    8. return o1.getSage()-o2.getSage();
    9. }
    10. });
    11. //stu.add(new Student(1,"苡桉",18));
    12. stu.add(new Student(1,"苡桉",18));
    13. stu.add(new Student(2,"千帆",19));
    14. stu.add(new Student(3,"鼠标",17));
    15. stu.add(new Student(7,"鼠标",18));
    16. stu.add(new Student(4,"耳机",22));
    17. stu.add(new Student(5,"安楠",30));
    18. stu.remove(new Student(3,"鼠标",17));
    19. for (Student s : stu) {
    20. System.out.println(s);
    21. }
    22. }

    效果图如下: 

     

  • 相关阅读:
    WebCPM:首个开源的交互式网页搜索中文问答模型
    python装饰器原理梳理
    在哪些场景下不建议自增数据库主键
    MySQL子查询
    Mediacodec 如何硬件解码到纹理的
    Rust所有权(非常重要)
    Dapr v1.9.0 版本已发布
    grafana 简介
    Redis高可用之持久化
    iconfont使用
  • 原文地址:https://blog.csdn.net/weixin_62270300/article/details/125495287