• Java中的set集合如何理解——精简


    引言

    在前面的内容中,我们先是一一介绍了Collection集合中都有哪些种类的集合,并且详细地讲解了List集合中的相关知识,那么今天我们来详细地讲解一下Collection集合中的另外一个分支——Set系列集合。最后还是希望这一篇篇的文章能够对你在集合中的学习、Java中的学习起到一定的帮助作用,好了,闲话不多说直接步入正题吧。

    概念

    Set系类集合特点:

    •  无序:存取顺序不一致
    • 不重复:可以去除重复
    • 无索引:没有带索引的方法,所以不能使用普通for循环遍历,也不能通过索引来获取元素

    Set集合实现类特点:

    HashSet:无序、不重复、无索引

    LinkedHashSet:有序、不重复、无索引

    TreeSet:排序、不重复、无索引

    Set集合的功能上基本上与Collection的API一致。

     HashSet集合

    HashSet集合:

    1. Set<String> set = new HashSet<>();
    2. set.add("石原里美");
    3. set.add("石原里美");
    4. set.add("工藤静香");
    5. set.add("朱茵");
    6. System.out.println(set);
    7. set.remove("朱茵");
    8. System.out.println(set);

     输出结果:

     通过上述代码与运行结果,我们可以清晰地看出,HashSet集合无序、不重复的特性;

    结合上述图片所示,可以看出HashSet集合是无法通过get()方法的索引获取数据的,并且在删除集合中的数据的时候,也只能通过定向的对数据进行删除。 

     LinkedHashSet集合:

    LinkedHashSet集合:

    1. Set<String> set = new LinkedHashSet<>();
    2. set.add("石原里美");
    3. set.add("石原里美");
    4. set.add("工藤静香");
    5. set.add("朱茵");
    6. System.out.println(set);
    7. set.remove("朱茵");
    8. System.out.println(set);

    输出结果:

    通过上述代码与输出结果做对比,即可看出无序与有序之间的区别,前者是会将传入的数据顺序打乱,而后者则是仍然按照输入数据的顺序存储数据,因此输出的时候是有序状态。 

    TreeSet集合: 

    TreeSet集合:

    1. Set<Integer> set = new TreeSet<>();
    2. set.add(13);
    3. set.add(23);
    4. set.add(23);
    5. set.add(11);
    6. System.out.println(set);
    7. set.remove(23);
    8. System.out.println(set);

     输出结果:

     通过上述代码和输出结果我们便可以通过字面意思去理解为什么TreeSet的特点是排序了,即将存储的数据按照Java默认的排序方式进行排序。

    然而此时若存储自定义如People对象,TreeSet无法直接排序,会出现报错的情况!

    1. //People类:
    2. public class People{
    3. private String name;
    4. private int age;
    5. private String classroom;
    6. public People(){
    7. }
    8. public People(String name, int age, String classroom) {
    9. this.name = name;
    10. this.age = age;
    11. this.classroom = classroom;
    12. }
    13. public String getName() {
    14. return name;
    15. }
    16. public void setName(String name) {
    17. this.name = name;
    18. }
    19. public int getAge() {
    20. return age;
    21. }
    22. public void setAge(int age) {
    23. this.age = age;
    24. }
    25. public String getClassroom() {
    26. return classroom;
    27. }
    28. public void setClassroom(String classroom) {
    29. this.classroom = classroom;
    30. }
    31. @Override
    32. public String toString() {
    33. return "People{" +
    34. "name='" + name + '\'' +
    35. ", age=" + age +
    36. ", classroom='" + classroom + '\'' +
    37. '}';
    38. }
    39. }
    40. //main方法:
    41. public static void main(String[] args) {
    42. Set<People> p = new TreeSet<>();
    43. p.add(new People("张三",19,"智能"));
    44. p.add(new People("李四",18,"数据库"));
    45. p.add(new People("王五",20,"渗透"));
    46. System.out.println(p);
    47. }

    若想解决该问题,我们就需要为TreeSet集合自定义存储类型,现有两种方式可以解决该问题:一种是自定义类实现Comparable接口并重写里面的compareTo方法指定规则;另一种则是集合自带比较器对象进行规则定义。

    方式一:自定义类实现Comparable接口重写里面的compareTo方法指定比较规则(多余无关紧要的代码在此不再赘述了,只展示重要的那部分代码)

    1. //改变的第一个地方:实现Comparable类
    2. public class People implements Comparable<People> {
    3. //改变的第二个地方:重写Comparable类中的compareTo方法
    4. @Override
    5. public int compareTo(People o) {
    6. return this.age-o.age;
    7. }
    8. }

    输出结果(根据年龄进行比较): 

    在重写的方法中,return后面的代码决定了该对象将要根据什么准则进行比较,比较规则如下:

    • 如果认为第一个元素大于第二个元素返回正整数即可
    • 如果认为第一个元素小于第二个元素返回负整数即可
    • 如果认为第一个元素等于第二个元素返回0即可,此时Treeset集合只会保留一个元素,认为两者重复

    方式二:集合自带比较器对象进行规则定义

    1. Set<People> p = new TreeSet<>(new Comparator<People>() {
    2. @Override
    3. public int compare(People o1, People o2) {
    4. return o1.getAge()-o2.getAge();
    5. }
    6. });

    在原来的基础之上对集合的创建作出改变,并且其比较准则与前面的定义方法类似,相对前面的方式,这种方式会更加方便快捷一些。在此,我们也可以回顾一些前面所学到的知识“Lambda表达式”,对给代码块进行化简。

    Set<People> p = new TreeSet<>((o1, o2) -> o1.getAge()-o2.getAge());

    如果没有学习过Lambda表达式,或者说是对Lambda表达式的知识不清晰,那么可以可以看Java中的lambda表达式如何理解——精简这篇文章的讲解,或许会对你有所帮助的。

    实战场景 

    • 元素可以重复、又有索引、索引查询速度快

    使用ArrayList集合,基于数组

    •  元素可以重复、又有索引、增删首尾操作快

    使用LinkedList集合,基于链表

    • 增删查改快,但是元素不重复、无序、无索引

    使用HashSet集合,基于哈希表

    • 增删查改快,但是元素不重复、有序、无索引

    使用LinkedHashSet集合,基于哈希表和双链表

    • 需要对对象进行排序

    使用TreeSet集合,基于红黑树,后续也可以使用List集合实现

    创作不易,给个三连吧 

  • 相关阅读:
    网络安全(黑客)自学笔记
    [附源码]计算机毕业设计基于Springboot的中点游戏分享网站
    C++ 11的移动语义 - 清晰的示例及浅显的说理
    easycms v5.5 分析 | Bugku S3 AWD排位赛
    POSIX 真的不适合对象存储吗?
    Python Interview Question Summary part 1
    idea中往git上上传项目步骤
    什么是架构
    黑炫酷的监控界面,实际上是用了什么开源工具?
    C. Make it Alternating
  • 原文地址:https://blog.csdn.net/weixin_50635856/article/details/124806587