java.util.Collection源码分析和深度讲解
java.util.Collection源码分析和深度讲解
写在开头
java.util.Collection 作为Java开发最常用的接口之一,我们经常使用,今天我带大家一起研究一下Collection接口,希望对大家以后的编程以及系统设计能有所帮助,本文所研究的jdk版本为jdk1.8.0_131
明确一下几点:
-
- Collection是接口,其继承了Iterable接口
- Collection属于单值类型集合,重点子接口List接口和Set接口
Java.util.List接口(有序、不唯一)
ArraryList
ArrayList 是一个数组队列,相当于 动态数组。与Java中的数组相比,它的容量能动态增长。它继承于AbstractList,实现了List, RandomAccess, Cloneable, java.io.Serializable这些接口。ArrayList是非同步的,效率高但是线程不安全,Collections.sychromiziedList(new ArraryList<>());可以让那个ArrayList变成线程安全类
-
- ArrayList是基于动态数组实现的,在增删时候,需要数组的拷贝复制。
-
- ArrayList的默认初始化容量是10,每次扩容时候增加原先容量的一半,也就是变为原来的1.5倍
-
- 删除元素时不会减少容量,若希望减少容量则调用trimToSize()
-
- 它不是线程安全的。它能存放null值。
LinkedList
LinkedList是一个双向循环列表队列
-
- LinkedList 是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。
- LinkedList 实现 List 接口,能对它进行队列操作。
- LinkedList 实现 Deque 接口,即能将LinkedList当作双端队列使用。
- LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。
- LinkedList 实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。
- LinkedList 是非同步的。
Vector
-
-
底层是数组,现在已少用,被ArrayList替代,原因有两个:
-
-
- Vector所有方法都是同步,有性能损失。
-
- Vector初始length是10 超过length时 以100%比率增长,相比于ArrayList更多消耗内存。
-
- 参考资料:https://www.zhihu.com/question/31948523/answer/113357347
总的来说:查询多用ArrayList,增删多用LinkedList。
ArrayList增删慢不是绝对的(在数量大的情况下,会有例外):
-
- 如果增加元素一直是使用
add()
(增加到末尾)的话,并且不扩容的情况下) - 一直删除末尾的元素也是ArrayList要快【不用复制移动位置】
- 至于如果删除的是中间的位置的话,还是ArrayList要快!
- 如果增加元素一直是使用
但一般来说:增删多还是用LinkedList,因为上面的情况是极端的~
Java.util.Set接口(无序、唯一)
|——SortedSet接口——TreeSet实现类
Set接口——|——HashSet实现类
|——LinkedHashSet实现类
hashSet
hashSet底层基于hashMap实现,如图
hashSet中的add()方法,是将对象E放入hashMap中的key的位置,value位置存放的是一个固定的Object,如图:
HashSet是无序唯一的,当元素为自定义对象时,两者的hashCode不同,被认为是不同的元素从而被允许放入HashSet中,但这不符合实际的生产意义,因此需要让其判定位相等,就要重写hashCode(),然而重写HashCode(),会出现重码的bug,因此需要重写equals()来解决
添加元素的时候,如果key(也对应的Set集合的元素)相等,那么则修改value值。而在Set集合中,value值仅仅是一个Object对象罢了(该对象对Set本身而言是无用的)。
也就是说:Set集合如果添加的元素相同时,是根本没有插入的(仅修改了一个无用的value值),从源码(HashMap)中也看出来,==和equals()方法都有使用,具体过程如下
-
- 新元素的hsah是否等于老元素的hash,如果不相等,则元素不同,如果相等,那么进行第二部比较
- 新元素与老元素用“==”进行比较,如果相等,则为同一元素,若不同则进行第三部比较
- 新元素和老元素用equals()方法判定是否相等,如果不等则不是同一元素,如果相等那么结果为:两个元素不是同一个对象,程序想把它们当成同一个对象,因此重写了equals方法;
TreeSet
与HashSet是基于HashMap实现一样,TreeSet同样是基于TreeMap实现的。
TreeSet是SortedSet接口的唯一实现类,TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方式,自然排序 和定制排序,其中自然排序为默认的排序方式。向 TreeSet中加入的应该是同一个类的对象。
LinkedHashSet
LinkedHashSet是HashSet的一个“扩展版本”,HashSet并不管什么顺序,不同的是LinkedHashSet会维护“插入顺序”。HashSet内部使用HashMap对象来存储它的元素,而LinkedHashSet内部使用LinkedHashMap对象来存储和处理它的元素
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Java线程池,你了解多少?
Java线程池,你了解多少? 阅读目录 一、前言 二、那么线程池有哪些作用呢? 三、线程池中核心类:ThreadPoolExecutor 四、关于线程池使用的注意事项 五、总结&推荐学习 六、参考资料 回到顶部 一、前言 随着业务的发展,单线程已经远远不能满足,随即就有多线程的出现。多线程虽然能解决单线程解决不了的事情,但是它也会给你带来额外的问题。比如成千上万甚至上百万的线程时候,你系统就会出现响应延迟、卡机、甚至直接卡死的情况。为什么会出现这样的原因呢?因为为每个请求创建一个新线程的开销很大:在创建和销毁线程上花费的时间和消耗的系统资源要比花在处理实际的用户请求的时间和资源更多。 除了创建和销毁线程的开销之外,活动的线程也消耗系统资源。在一个 JVM里创建太多的线程可能会导致系统由于过度消耗内存而用完内存或“切换过度”。所以为了防止资源不足,服务器应用程序需要一些办法来限制任何给定时刻处理的请求数目。而线程池为线程生命周期开销问题和资源不足问题提供了解决方案。 回到顶部 二、那么线程池有哪些作用呢? 1、降低资源消耗,防止资源不足。合理配置线程池中的线程大小,防止请求线程猛...
- 下一篇
Python发送邮件
发送邮件的Demo: 使用smtp服务必须在相应邮箱服务器设置中开启SMTP服务,并且生成授权码 例如QQ: import smtplib from email.mime.text import MIMEText #第三方SMTP服务 mail_host = "smtp.qq.com" mail_user = "wsyjlly@foxmail.com" mail_pass = "授权码" sender = "wsyjlly@foxmail.com" receiver = "wsyjlly@foxmail.com" message = MIMEText("你好,世界!") message["From"] = sender message["To"] = receiver message["Subject"] = "一起嗨吧!" def send_email(): try: server = smtplib.SMTP() server.connect(mail_host) server.login(mail_user,mail_pass) server.sendmail(sender,...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- MySQL8.0.19开启GTID主从同步CentOS8
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Windows10,CentOS7,CentOS8安装Nodejs环境
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS7设置SWAP分区,小内存服务器的救世主