Java复习-集合篇

集合

集合分为俩大类

  • 单列集合
    • 每个元素数据只包含一个值
  • 双列集合
    • 每个元素包含俩个键值对

image-20240526084729889

Conllection单列集合

单列集合常用的主要是下列几种

image-20240526085320294

List集合

List系列集合的特点:添加元素是有序、可重复、有索引

这里我们来试一下ArrayList

        ArrayList<String> list = new ArrayList<>();
        list.add("java1");
        list.add("java2");
        list.add("java1");
        list.add("java2");
        System.out.println(list);

image-20240526090326298

ArrayList底层原理

基于数据实现

特点:索引查询快,添加删除慢

  1. 利用无参构造器创建集合,会在底层创建一个默认长度为0的数组

    image-20240526095455113

  2. 添加第一个元素,底层会创建一个新的长度为10的素组

    image-20240526095511543

  3. 存满时,会扩容1.5倍

  4. 如果一次添加多个数据,1.5倍还放不下,则会以实际为准

应用场景

  1. 适合:根据索引查询数据,比如根据随机索引取数据,或者数据量不是很大的
  2. 不适合:数据量大的同时,又要频繁的进行增删操作

LinkedList底层原理

基于双链表实现

特点:查询慢、增删快,尤其是首尾节点速度

image-20240526100236092

应用场景

  1. 设计队列 (queue适用于校号系统、排队系统)

    image-20240526100333799

    
    /**
    * 模拟队列
    */
    LinkedList<String> queue = new LinkedList<>();
    
    //入队
    queue.addLast("第一个人");
    queue.addLast("第二个人");
    queue.addLast("第三个人");
    queue.addLast("第四个人");
    System.out.println(queue);
    
    //出队
    System.out.println(queue.removeFirst());
    System.out.println(queue.removeFirst());
    System.out.println(queue.removeFirst());
    System.out.println(queue);
    

    image-20240526101734173

  2. 设计栈(Stack)

/*
* 模拟栈
* */
LinkedList<String> stack = new LinkedList<>();
//入栈
stack.push("第一颗子弹");
stack.push("第二颗子弹");
stack.push("第三颗子弹");
stack.push("第四颗子弹");
System.out.println(stack);

//出栈 
System.out.println(stack.pop());
System.out.println(stack.pop());
System.out.println(stack.pop());
System.out.println(stack);

注意这里的 push 和 pop 就是addfirst 和 removeFirst

image-20240526101539112

image-20240526101621169

Set集合

Set系列集合的特点:添加元素是无序、不可重复、无索引

注意这俩个特别:

  • LinkedHashSet:有序、不重复、无索引
  • TreeSet:按照大小默认升序排序、不重复、无索引

然后我们来试一试HashSet集合

        HashSet<String> set = new HashSet<>();
        set.add("java1");
        set.add("java2");
        set.add("java1");
        set.add("java2");
        System.out.println(set);

image-20240526090530065

HashSet底层原理

基于哈希表实现

特点:增删改查都较好

1.8之前

JDK8之前哈希表:数组+链表

  1. 创建一个默认为16的数组 默认加载因子为0.75表名为table

    image-20240526103135020

  2. 使用元素的哈希值数组长度求余计算出应存入的位置(这里的求余是它独有的算法,并不是我们直接的%求余,确保它为正数)

  3. 判断当前位置是否为null,如果是null直接存入

    image-20240526103332391

  4. 如果不为null,如果有元素,则调用equals方法比较(相等,则不存;不相等,则存入数组)

    1. JDK8之前,新元素会存入数组,占用老元素位置,老元素挂在下面

    image-20240526103610692

1.8之后

JDK8之后哈希表:数组+链表+红黑树

当链表长度超过8,且数组长度>=64时,自动将链表转为红黑树

image-20240526104109437

image-20240526104119591

LinkedHashSet底层原理

基于哈希表来实现

但是,每个元素都多了一个双链表机制来记录前后元素的位置

image-20240528101238298

TreeSet底层原理

特点:可排序(默认升序,按照元素大小,由小到大)

底层基于红黑树实现

总结

image-20240528102747856

集合并发修改异常错误

使用迭代器遍历集合时,又同时在删除集合中的数据,程序就会出现并发修改异常的错误。

底层原因是因为集合删除后会改变原集合的大小,而指针会自动往后移造成数据的漏删

例如

//删除名中有李字的
["张三","李四","五李","王五"]
   i
//第一次
 ["张三","李四","五李","王五"]
           i
//删除 后指针指向五李
["张三","五李","王五"]   
         i
 //继续
["张三","五李","王五"]   
                 i

上面这种情况就会造成异常错误

解决方法呢,就是在每次删除之后将i向前移,迭代器底层也是这样实现的

Map双列集合

每次存储需要一对数据作为一个元素

Map中的键是不允许重复的,但是值可以

HashMap底层原理

特点:无序、不重复、无索引

底层:基于哈希表实现

实际上:原来所有的Set系列的集合都是基于Map实现的,只是Set集合中的元素只要键数据,不要值数据

image-20240528165828230

image-20240528165858677

注意的是底层这里计算hash值是基于键来进行hash表计算

image-20240528170054305

LinkedHashMap底层原理

特点:有序、不重复、无索引

底层:基于哈希表实现,但是多了一个双链表机制来记录元素顺序(保证有序)

实际上:原来学习的LinkedHashSet集合的底层原理就是LinkedHashMap。

image-20240528170423776

image-20240528170511992

TreeMap底层原理

特点:不重复、无索引、可排序(按照键的大小默认升序排序,只能对键排序)

原理:跟TreeSet一样基于红黑树实现排序

  • 17
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周粥粥ya

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值