码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 【集合】单列集合


    集合

    • 单列集合Collection接口
    • List(有序可重复)
      • ArrayList
        • 底层:数组
        • 扩容:原始大小*1.5
          • [Arrays.copyOf() 用法](https://blog.csdn.net/qq_25131363/article/details/85001414)
        • 添加元素 add(E e)
        • 添加元素 add(int index, E element)
        • 移除元素
        • 扩展:[Arrays.copyOf() 和 System.arraycopy()区别](https://blog.csdn.net/yzx3105/article/details/128919833)
      • LinkedList
        • 底层:双向链表结构 pre|data|next <-> pre|data|next <-> pre|data|next
        • 扩容:无
        • 添加删除元素
    • Set(无序不可重复,无序是指存储的数据在底层数组中并非按照数组索引的顺序添加 ,而是根据数据的哈希值决定的。)
      • HashSet
        • 底层:HashMap(把数据作为K值,而V值一直使用一个相同的虚值来保存)
      • TreeSet
        • 底层:红黑树,元素是有序的,排序的方式有自然排序和定制排序。
    • 面试题
      • 1. ArrayList 与 LinkedList 区别?
      • 2. Array 和 ArrayList 有什么区别?什么时候该应 Array 而不是 ArrayList 呢?
      • 3. [Java集合的快速失败机制 “fail-fast”?](https://blog.csdn.net/yzx3105/article/details/128920989)

    单列集合Collection接口

    List(有序可重复)

    ArrayList

    底层:数组

    扩容:原始大小*1.5

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    Arrays.copyOf() 用法

    Arrays的copyOf()方法传回的数组是新的数组对象,改变传回数组中的元素值,不会影响原来的数组。
    copyOf()的第二个自变量指定要建立的新数组长度,如果新数组的长度超过原数组的长度,则填充类型默认值,String类型填充null。int类型填充0

    添加元素 add(E e)

    在这里插入图片描述

    添加元素 add(int index, E element)

    比如有下面这样一个数组我需要在index 5的位置去新增一个元素A
    3.
    复制了一个数组,是从index 5的位置开始的,然后把它放在了index 5+1的位置
    在这里插入图片描述
    给我们要新增的元素腾出了位置,然后在index的位置放入元素A就完成了新增的操作了
    在这里插入图片描述
    在这里插入图片描述

    移除元素

    我们现在要删除下面这个数组中的index5这个位置
    在这里插入图片描述
    那代码他就复制一个index5+1开始到最后的数组,然后把它放到index开始的位置
    在这里插入图片描述
    index5的位置就成功被”删除“了其实就是被覆盖了,给了你被删除的感觉。
    在这里插入图片描述
    按着上图示例:
    index = 4,size = 9;
    numMoved = 9-4-1;//4
    也就是从index+1位置开始拷贝,拷贝4个元素,至index位置上。从元素5开始往后拷贝4个元素。
    最后最后一个元素手动置为null,size–

    扩展:Arrays.copyOf() 和 System.arraycopy()区别

    LinkedList

    底层:双向链表结构 pre|data|next <-> pre|data|next <-> pre|data|next

    扩容:无

    添加删除元素

    在这里插入图片描述

    Set(无序不可重复,无序是指存储的数据在底层数组中并非按照数组索引的顺序添加 ,而是根据数据的哈希值决定的。)

    HashSet

    底层:HashMap(把数据作为K值,而V值一直使用一个相同的虚值来保存)

    public boolean add(E e) {
        return map.put(e, PRESENT)==null;// 调用HashMap的put方法,PRESENT是一个至始至终都相同的虚值
    }
    
    • 1
    • 2
    • 3

    TreeSet

    底层:红黑树,元素是有序的,排序的方式有自然排序和定制排序。

    面试题

    1. ArrayList 与 LinkedList 区别?

    ArrayListLinkedList
    是否保证线程安全线程不安全线程不安全
    底层数组双向链表
    插入和删除是否受元素位置的影响ArrayList 采用数组存储,所以插入和删除元素的时间复杂度受元素位置的影响。 比如:执行add(E e)方法的时候, ArrayList 会默认在将指定的元素追加到此列表的末尾,这种情况时间复杂度就是 O(1)。但是如果要在指定位置 i 插入和删除元素的话(add(int index, E element))时间复杂度就为 O(n-i)。因为在进行上述操作的时候集合中第 i 和第 i 个元素之后的(n-i)个元素都要执行向后位/向前移一位的操作。LinkedList 采用链表存储,所以,如果是在头尾插入或者删除元素不受元素位置的影响(add(E e)、addFirst(E e)、addLast(E e)、removeFirst() 、 removeLast()),时间复杂度为 O(1),如果是要在指定位置 i 插入和删除元素的话(add(int index, E element),remove(Object o)), 时间复杂度为 O(n) ,因为需要先移动到指定位置再插入。
    是否支持快速随机访问ArrayList 支持。快速随机访问就是通过元素的序号快速获取元素对象(对应于get(int index)方法)不支持

    2. Array 和 ArrayList 有什么区别?什么时候该应 Array 而不是 ArrayList 呢?

    Array 可以包含基本类型和对象类型,ArrayList 只能包含对象类型。
    Array 大小是固定的,ArrayList 的大小是动态变化的。

    3. Java集合的快速失败机制 “fail-fast”?

    是java集合的一种错误检测机制,当多个线程对集合进行结构上的改变的操作时,有可能会产生 fail-fast 机制。
    例如:假设存在两个线程(线程1、线程2),线程1通过Iterator在遍历集合A中的元素,在某个时候线程2修改了集合A的结构(是结构上面的修改,而不是简单的修改集合元素的内容),那么这个时候程序就会抛出 ConcurrentModificationException 异常,从而产生fail-fast机制。
    原因:迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个 modCount 变量。集合在被遍历期间如果内容发生变化,就会改变modCount的值。每当迭代器使用hashNext()/next()遍历下一个元素之前,都会检测modCount变量是否为expectedmodCount值,是的话就返回遍历;否则抛出异常,终止遍历。
    解决办法:

    1. 在遍历过程中,所有涉及到改变modCount值得地方全部加上synchronized。
    2. 使用CopyOnWriteArrayList来替换ArrayList

    ArrayList 内容来源:https://blog.csdn.net/qq_35190492/article/details/103883964
    ArrayList源码分析参考:https://blog.csdn.net/lkp1603645756/article/details/81264257

  • 相关阅读:
    【opencv图像处理】--1. 图像,视频,鼠标,trackbar控件简单使用
    运维实战100:CDH5.16.2升级至CDH6.3.2
    Scrapy运行爬虫文件报错:ValueError: attempted relative import beyond top-level package
    「OSS中间件系列」Minio的文件服务的存储模型及整合Java客户端访问的实战指南
    【历史上的今天】6 月 23 日:图灵诞生日;互联网奠基人出生;Reddit 上线
    Java编程基础
    kubesphere安装部署(可离线部署)
    docker打包chatpdf(自写)
    数组模拟环形队列实现
    Python网络编程(socket)
  • 原文地址:https://blog.csdn.net/yzx3105/article/details/126932597
  • 最新文章
  • 【JVM】编译执行与解释执行的区别是什么?JVM 使用哪种方式?
    用 Hashids 优雅解决 C 端自增 ID 暴露问题
    V8引擎 精品漫游指南--Ignition篇(上) 指令 栈帧 槽位 调用约定 内存布局 基础内容
    LLVM Pass快速入门(四):代码插桩
    milkup:桌面端 markdown AI续写和即时渲染
    基于项目工程构建SBOM(软件物料清单)的研究
    鸿蒙应用开发UI基础第二节:鸿蒙应用程序框架核心解析与实操
    .NET 中如何快速实现 List 集合去重?
    扣子Coze实战:从0到1打造抖音+小红书热点监控智能体
    浅谈数据访问层
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
小工具 小游戏
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

京公网安备 11010502049817号