由于本人对多线程板块知识理解的深度不够,所以本文结合了网上面试题的同时略过了ArrayList与多线程结合的题目,或许那才是重点。不过咱们是初学者,先了解就行,不用深究。

文章目录

  • 1、List概述
  • 2、ArrayList基本概述
  • 3、常见的ArrayList面试题
    • 3.1、ArrayList是如何进行扩容的
    • 3.2、为什么ArrayList获取集合的长度是使用size,而不是使用length
    • 3.3、ArrayList频繁扩容导致添加性能急剧下降,如何处理?
    • 3.4、如何复制一个ArrayList到另一个ArrayList中去
    • 3.5、 ArrayList和LinkedList区别?
    • 3.6、ArrayList是线程安全的么?如果不安全,又需要安全怎么办
    • 3.7、对于ArrayList和LinkedList如何选择使用?

写在前头

学完集合的源码,整个人都不好了。以前只知道List、Set、Map三种集合,然后就是对应的增删改查方法,哇,使用集合存数据方便极了,谁还用难用的数组!!!凡是多问几个为什么,你不问,面试官帮你问。好的,所以为了赶在面试官前面,我先来问问自己为什么。
于是就有了你看的这篇博客,当然这仅仅是来自一个初学ArrayList集合的人,知识体系也就不够完善,但是我会加油的,希望对你也有帮助!!!

不过不得不说ArrayList的源码要比HashMap简单很多,只有逻辑代码,很少涉及算法部分(那些二进制算法)。废话不多说,咱们开始吧!!!

建议本文可以配合源码食用

传送门

ArrayList源码剖析


1、List概述

Java 的 List 是非常常用的数据类型。List 是有序的 Collection。Java List 一共三个实现类:

分别是 ArrayList、Vector 和 LinkedList,所以ArrayList也是有序的。下面的图片分别是三种集合的类图,有兴趣的可以了解一下,当然后期我也会继续跟进,毕竟熟透框架 人人有责。


2、ArrayList基本概述

ArrayList是一个数组队列,相当于动态数组。与Java中的数组相比,它的容量能动态增长。它继承于AbstractList,实现了List,RandomAccess,Cloneable,java.io.Serializable这些接口

ArrayList 是最常用的 List 实现类,内部是通过数组实现的,它允许对元素进行快速随机访问。数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要将已经有数组的数据复制到新的存储空间中。当从 ArrayList 的中间位置插入或者删除元素时,需要对数组进行复制、移动、代价比较高。因此,它适合随机查找和遍历,不适合插入和删除。


3、常见的ArrayList面试题

3.1、ArrayList是如何进行扩容的

当我们在使用add()方法时,如果我们没有指定对应的容量,系统就会采用默认的10作为集合的容量。(至于为什么是10,我觉得应该是作者综合考虑了很多因素才决定的吧,毕竟扩容挺浪费性能的)当集合的容量超过10以后,集合的容量就开始扩容,每次扩容为之前容量的1.5倍(oldCapacity + (oldCapacity >> 1))。当然,每次调用add()方法的时候,都会去进行容量的判断,继而确定是否扩容。

3.2、为什么ArrayList获取集合的长度是使用size,而不是使用length

在最开始接触集合的时候,老师就跟我们说,获取集合的长度是使用size(),而不是length。调用size()我们不难发现它也只是简单的返回一个size变量。那为什么就不能继续让length继续担任长度呢?

public int size() {return size;
}

其实在ArrayList中,有集合容量和集合长度一说。集合的容量就是使用的length(用于扩容),集合长度就是集合中真正的包含的元素使用size。并且我们ArrayList是不能够获取集合容量的,这也就是为什么我们的获取集合的长度是使用的size()而非length。

3.3、ArrayList频繁扩容导致添加性能急剧下降,如何处理?

我们分析源码可得,每次ArrayList集合在添加方法的时候,都会去进行集合容量的判定,继而确定是否需要进行扩容。如果我们能够指定出集合具体的恰当容量,那么系统就不会去扩容,直接使用我们设置的容量。这样就能够避免频繁扩容带来的性能损耗。

3.4、如何复制一个ArrayList到另一个ArrayList中去

1、由于ArrayList类实现了clone()接口,所以我们可以直接使用克隆的方式进行

2、在构造方法中传入集合对象,可以完成复制

3、使用addAll方法传入集合对象,可以完成复制

3.5、 ArrayList和LinkedList区别?

  • ArrayList

    • 基于动态数组的数据结构
    • 对于随机访问的get和set,ArrayList要优于LinkedList
    • 对于随机操作的add和remove,ArrayList并不一定比LinkedList慢 (虽然LinkedList在增删时拥有明显的优势,但是ArrayList底层由于是动态数组,因此并不是每次add和remove的时候都需要创建新数组)
  • LinkedList

    • 基于链表的数据结构
    • 对于顺序操作,LinkedList不一定比ArrayList慢
    • 对于随机操作,LinkedList效率明显较低(因为使用顺序访问只是在获取迭代器的时候进行了一次折半,然而随机操作每次都要去获取)

3.6、ArrayList是线程安全的么?如果不安全,又需要安全怎么办

ArrayList不是线程安全的,只能用在单线程环境下,多线程环境下可以考略使用Collections.synchronizedList(list)返回一个线程安全的ArrayList类。也可以使用ConcurrentLinkedQueue()来保证安全。

3.7、对于ArrayList和LinkedList如何选择使用?

时间复杂度上:

由于ArrayList是动态数组(动态就是可以自动扩容),所以改和查有明显的优势,但是增删由于涉及到扩容效率会相对差些,但并不是每次都会去扩容,所以ArrayList的增删效率差这种说法是有一定问题的。

LinkedList是一个双向链表,会出现在删除和修改上有明显的优势,但查找和修改就有一定的劣势,所以使用LinkedList一定要使用迭代器查找(具体原因在分析源码的时候,我已经说过)。

空间复杂度上:

这个点还真的不是那么好确定的。

ArrayList的容量在10以上时,每次扩容都是上一次的1.5倍,试想如果你现在的集合容量已经很大了,但是为了存最后一个数据,就有可能再次扩容,继而浪费了很多的空间。集合越大,浪费的就越多(当然你也可以通过指定集合大小来避免出现这种问题)。

LinkedList由于需要存储相应的头信息和尾信息,所以也会出现空间的浪费,不过还好,他每次添加的时候浪费的空间比较恒定。


想学习ArrayList源码的:

传送门走起

ArrayList源码剖析

好吧,我承认,这个集合没有什么太多的看点,丝毫没有我学习HashMap集合时候的那种兴奋(可能是因为里面没有算法吧)不过这个集合是通向List集合的大门,只有入了门,学其他两个同类的集合LinkedList、Vector才轻松,只是体系树才能更加茁壮成长呀。

不过源码真的有意思,能学到很多,特别是代码的书写方式

老掉牙的ArrayList解析它它它又来了相关推荐

  1. Android-Multidex安装流程解析

    Android-Multidex安装流程解析 关于为什么需要引入Multidex支持以及如何配置Multidex可参考官网,本篇不做阐述,本篇着重分析Multidex1.0.2源码进行分析 大家都知道 ...

  2. EasyExcel解析简易动态表头列及其简用

    前言 项目组祖传的POI代码,是基于entity实体类来固定格式解析,对应EXCEL是多少表头展示解析多少表头,需要改祖传代码,比较麻烦,时间不够.故用二次封装POI的EasyExcel来进行简易实现 ...

  3. DOM4J解析xml文件,递归遍历全部子节点

    业务需求是把图中的xml解析为如下格式的进行前端展示 ps:解析后用一个map来装,注意map的value是子节点名称,并不是节点值!!! map中的key为: 根节点名,用"-" ...

  4. 简单读!tomcat源码(一)启动与监听

    tomcat 作为知名的web容器,很棒! 本文简单了从其应用命令开始拆解,让我们对他有清晰的了解,揭开神秘的面纱!(冗长的代码流水线,给你一目了然) 话分两头: 1. tomcat是如何启动的? 2 ...

  5. Java使用POI读取和写入Excel指南

    Java使用POI读取和写入Excel指南 做项目时经常有通过程序读取Excel数据,或是创建新的Excel并写入数据的需求: 网上很多经验教程里使用的POI版本都比较老了,一些API在新版里已经废弃 ...

  6. Jsoup:使用Java将爬虫得到的数据写入Excel,Jsoup得到的数据进行持久化,爬虫数据保存到本地Excel中

    Jsoup:使用Java将爬虫得到的数据写入Excel,Jsoup得到的数据进行持久化,爬虫数据保存到本地Excel中 一.资源 EasyExcel使用教程 Jsoup爬虫教程 二.代码 xml依赖 ...

  7. Jsoup:用Java也可以爬虫,怎么使用Java进行爬虫,用Java爬取网页数据,使用Jsoup爬取数据,爬虫举例:京东搜索

    Jsoup:用Java也可以爬虫,怎么使用Java进行爬虫,用Java爬取网页数据,使用Jsoup爬取数据,爬虫举例:京东搜索 一.资源 为什么接下来的代码中要使用el.getElementsByTa ...

  8. 手把手教你搭建一个基于Java的分布式爬虫系统

    http://blog.51cto.com/xpleaf/2093952 1 概述 在不用爬虫框架的情况,经过多方学习,尝试实现了一个分布式爬虫系统,并且可以将数据保存到不同地方,类似MySQL.HB ...

  9. 分布式爬虫系统设计、实现与实战:爬取京东、苏宁易购全网手机商品数据+MySQL、HBase存储...

    http://blog.51cto.com/xpleaf/2093952 1 概述 在不用爬虫框架的情况,经过多方学习,尝试实现了一个分布式爬虫系统,并且可以将数据保存到不同地方,类似MySQL.HB ...

  10. mybatis源码刨析总结

    拉勾 mybatis 初始化 1.创建git仓库 1.新建一个目录 然后点击右键 git base here 创建git (会弹出一个窗口) 2.初始化 再窗口输入 git init 3.指定仓库 g ...

最新文章

  1. 搭建OpenStack中的glance报错 403 503
  2. 阿姨帮悬赏通缉,紧急扩散!
  3. 「C++: draft」一张图弄懂C++指针(*)和引用()以及深拷贝、浅拷贝
  4. solr定时实时重建索引和增量更新
  5. 7-3 括号匹配 (15 分)
  6. 弱电系统集成(收集)
  7. 腾讯宣布捐赠1亿元驰援河南;苹果回应iPhone 安全隐患;贝索斯完成10分钟太空之旅|极客头条...
  8. ubuntu 常用指令
  9. 用线程安全随机数解决Random在多线程中随机性重复的问题
  10. Labview 做二维码识别
  11. offer oracle svp_SVP学校转非SVP学校——最新规定详解
  12. idea 红色文件处理方法
  13. 常用的计算机辅助存储器有,重学大学计算机教程--辅助存储器(磁盘、磁带、固态硬盘)...
  14. 天心阁吉他神秘人专访
  15. linux中如何查看设备的设备号,查看 linux 设备号信息
  16. IEDA免费在线激活永久使用
  17. PHP教程电子版下载
  18. vue3中导出excel表格
  19. CoreDNS篇8-健康检查
  20. PHP 使用parse_ini_file读取文本文档遇到中文乱码问题

热门文章

  1. 使用koa托管静态资源文件
  2. MongoDB学习(黑马教程)-2-数据库MongoDB的导入文档和查询文档的操作
  3. oracle erp 用户手册,oracleerp用户手册-mrp
  4. python维度切片中三个是怎么取值的_总结python 多维切片之冒号和三个点的使用方法...
  5. html5变动标签新写法,HTML5新增的标签和废除的标签
  6. 斑能不能彻底去掉_鸡脖、猪脖子上有淋巴结,会有大量毒素、病菌?还能不能放心吃?...
  7. java spring 区别_关于java:Spring和Spring MVC框架有什么区别
  8. php mysql显示到页面上_从数据库调出数据显示到页面 PHP+Mysql+Html(简单实例)
  9. mysql rounddown_Is there a ROUNDDOWN() function in sql as there is in EXCEL
  10. 用Python开始机器学习(2:决策树分类算法)