Java基础(十三)——Collections、TreeSet、HashSet

Java基础(十三)——Collections、TreeSet、HashSet

一、Collections

1、Collections——针对Collection的工具类

一次性添加多个对象:
在这里插入图片描述

排序:
在这里插入图片描述

二、Set——无序不可重复集合

1、TreeSet

TreeSet的底层是红黑树。到红黑树之前会先经历二叉树。
底层代码块是 TreeMap

a、二叉树的增删改查

TreeSet<Integer> set = new TreeSet<>();
        System.out.println("---------添加--------");
        set.add(3);         //  添加
        set.add(7);
        set.add(5);
        set.add(9);
        set.add(2);
        Iterator<Integer> it = set.iterator();

        while (it.hasNext()){
    
    
            Integer num = it.next();
            System.out.println(num);
        }

        System.out.println("-------删除---------");
        set.remove(3);
        System.out.println(set);

        System.out.println("-------修改---------");
        //  先删除,后修改
        set.remove(2);
        set.add(5);

        //  遍历方式只能通过迭代器遍历

2、TreeSet添加功能的底层代码

在红黑树代码执行之前,会把数据先形成一个二叉树结构,再用红黑树进行平衡。这里先学习二叉树底层实现:

下面注释中:
红色文字为第一次执行结果。
蓝色文字为第二次执行结果。
绿色文字为第三次执行结果。
深灰色文字为第四次执行结果。
画xx的那部分,后面再讲。

该图观看顺序:从左到右,从上到下。每次所用到的代码区都可能不同。
在这里插入图片描述

a、底层代码详解——第一次添加

1、首先是TreeSet 的无参构造方法,创建TreeMap对象,赋值给下面的有参构造方法,赋值给m,然后又赋值给
下面的m。
2、然后到 add()方法,return 那块的m.put,m就是TreeMap。接着就是调用 put 方法。
3、put方法这里,key 就是传递进来的值“5”,就是add方法里面返回值的put方法的形参 e,旁边的形参看全
大写和斜体就知道是静态常量,这个值哪里都一样,不改变,就不用管。
4、接着到Entry,以及旁边的root,点击打开可以发现,这个root没有值,之前的代码也没有赋值,所以
t == null5、接着执行到if(t == null)里面的代码。然后到compare方法,传递了两个5进去,接着执行方法,可以发现
这个方法没有接收返回值,只要不报错就不影响后续代码执行。点击comparator,进去里面可以看到是null,然
后执行三目运算,执行冒号左边,可以发现这里在做强转。点击Comparable发现里面是个接口,所以要求k1要实现
Comparable接口,没实现不能强转。这里k1是“5”,是要存储进集合的对象。这里的代码就要求做一件事,要求
存储的对象实现Comparable接口,且不能为null。不实现会报类型转换异常,为null会空指针异常。
6、接着到root=new Entry那行,这里key是5,储存进去,(这里代码在图片右下角)存储进去以后,顺明这里
开始有第一个节点了,此时开始,root代表第一个节点。
7、然后执行到 return null,第一次添加就结束了。

b、底层代码详解——第二次添加

敬请期待...

3、重写方法,自定义实现排序功能

敬请期待...

自然排序:存储进 TreeSet 集合的对象类必须实现 Comparable 接口,重写 conpareTo(),在 compareTo 里制定排序规则,返回正数存储的对象往右子树方向,返回负数存储的对象往左子树方向,返回0则不存储。

4、比较器

敬请期待...

比较器:在创建 TreeSet 集合对象的时候,传递 Comparator 接口的实现类对象,重写 Comparator 接口的 compare(),在 compare()里指定排序规则。

5、自然排序 对比 比较器

自然排序要重写 Comparable 接口的conpareTo()方法。
比较器要重写 Comparator 接口的 compare()方法。

  1. 使用自然排序需要改变存储对象类的结构。
  2. 使用比较器会额外添加多一个类(匿名内部类)。
  3. 当比较器与自然排序共存的时候,使用比较器进行排序。

6、TreeSet总结

1、无序可排序,不可重复,不能存储 null 对象的集合。
2、使用 TreeSet 存储对象,对象类要么实现自然排序,要么传递比较器

三、HashSet

1、HashSet总结

直接上总结:

HashSet:无序不可重复,可以存储 null 对象。

jdk1.7和jdk1.8不同,有区别:

jdk1.7:hash表(数组+链表)
jdk1.8:hash表(动态数组+链表+红黑树)

HashSet存储原理:
	通过 HashSet 存储对象,会根据对象的 hashCode() 生成 hash 值,根据 hash 生成索引,根据索引找
到hash 表中的位置;判断位置上是否有对象,没有对象直接插入,有对象则通过 equals() 判断内容是否相同,
如果相同则不插入,不同则根据链表往下检索,直到重复或者链表没有下一个对象,准备插入最后的时候判断链表
是否超过 8 个对象,当链表超过 8 个对象时,总存储的对象大于等于 64 则把链表转换成红黑树当 hash 表
总存储的对象大于负载因子值(0.75),则会进行数组的扩容,扩容为原本的 2 倍。

2、用法

HashSet 的用法跟前面 TreeSet 的用法基本一致,但是要注意,存储自定义对象,如果要实现无序不可重复这个特性,需要实现两个方法:equals()和 hashCode(),只有重写了这两个办法才能实现这个特性,在 IDEA里直接快捷键即可快速出代码:
在这里插入图片描述
创建普通的实体类,然后正常使用即可:
在这里插入图片描述
可以发现,重复的并没有出现在里面。

猜你喜欢

转载自blog.csdn.net/qq_41824825/article/details/121274426
今日推荐