范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

送分题,ArrayList的扩容机制了解吗?

  1. ArrayList 了解过吗?它是啥?有啥用?
  众所周知,Java 集合框架拥有两大接口 Collection 和 Map,其中,Collection 麾下三生子 List、Set 和 Queue。ArrayList 就实现了 List 接口,其实就是一个数组列表,不过作为 Java 的集合框架,它只能存储对象引用类型,也就是说当我们需要装载的数据是诸如 int、float 等基本数据类型的时候,必须把它们转换成对应的包装类。
  ArrayList 的底层实现是一个 Object 数组:
  既然它是基于数组实现的,数组在内存空间中是连续分配的,那必然查询速率非常快,不过当然也肯定逃不过增删效率低的缺陷。
  另外,和 ArrayList 一样同样实现了 List 接口的、我们比较常用的还有 LinkedList。LinkedList 比较特殊,它不仅实现了 List 接口,还实现了 Queue 接口,所以你可以看见 LinkedList 经常被当作队列使用: Queue queue = new LinkedList<>();
  LinkedList 人如其名,它的底层自然是基于链表的,而且还是个双向链表。链表的特性和数组正好是反的,由于没有索引,所以查询效率低,但是增删速度快。
  2. ArrayList 如何指定底层数组大小的?
  OK,首先,既然咱真正存储数据的地方是数组,那我们初始化 ArrayList 的时候自然要给数组分配一个大小,开辟一个内存空间。我们先来看看 ArrayList 的无参构造函数:
  可以看到,它为底层的 Object 数组也就是 elementData 赋值了一个默认的空数组 DEFAULTCAPACITY_EMPTY_ELEMENTDATA。也就是说,使用无参构造函数初始化 ArrayList 后,它当时的数组容量为 0 。
  这给咱初始化一个容量为 0 的数组有啥用?啥也存不了啊?别急,如果使用了无参构造函数来初始化 ArrayList, 只有当我们真正对数据进行添加操作 add时,才会给数组分配一个默认的初始容量 DEFAULT_CAPACITY = 10。看下图:
  说完了无参构造,ArrayList 的有参构造函数就是中规中矩了,按照用户传入的大小开辟数组空间:
  3. 数组的大小一旦被规定就无法改变,那 ArrayList 是怎么对底层数组进行扩容的?
  ArrayList 的底层实现是 Object 数组,我们知道,数组的大小一旦被规定就无法改变。那如果我们不断的往里面添加数据的话,ArrayList 是如何进行扩容的呢?或者说 ArrayList 是如何实现存放任意数量对象的呢?
  OK,扩容发生在啥时候?那肯定是我们往数组中新加入一个元素但是发现数组满了的时候。没错,我们去 add 方法中看看 ArrayList 是怎么做扩容的:
  ensureExplicitCapacity 判断是否需要进行扩容,很显然,grow 方法是扩容的关键:
  说实话,别的都不用看了,看上面图中的黄色框框就知道 ArrayList 是怎么扩容的了:扩容后的数组长度 = 当前数组长度 + 当前数组长度 / 2。最后使用 Arrays.copyOf 方法直接把原数组中的数组 copy 过来,需要注意的是,Arrays.copyOf 方法会创建一个 新数组 然后再进行拷贝。
  举个例子画个图来演示一下:
  4. 既然扩容发生在添加数据的时候,讲讲 ArrayList 具体是怎么添加数据的
  OK,add 方法我们刚刚讲了一半,添加数据前会先判断一下是否需要扩容,真正的添加数据的操作在下半部分:
  先讲下 add(int index, E element) 这个方法的含义,就是在指定索引 index 处插入元素 element。比如说 ArrayList.add(0, 3),意思就是在头部插入元素 3。
  再来看看 add 方法的核心 System.arraycopy,这个方法有 5 个参数: elementData:源数组 index:从源数组中的哪个位置开始复制 elementData:目标数组 index + 1:复制到目标数组中的哪个位置 size - index:要复制的源数组中数组元素的数量
  解释一下上面代码中 arraycopy 的意思,举个例子,我们想要在 index = 5 的位置插入元素,首先,我们会复制一遍源数组 elementData(这里我们称复制的数组为新数组吧),然后把源数组中从 index = 5 的位置开始到数组末尾的元素,放到新数组的 index + 1 = 6 的位置上:
  于是,这就给我们要新增的元素腾出了位置,然后在新数组 index = 5 的位置放入元素 element 就完成了添加的操作:
  显然,不用多说,ArrayList 的将数据插入到指定位置的操作性能非常低下,因为要开辟新数组复制元素啊,要是涉及到扩容那就更慢了。
  另外,ArrayList 还内置了一个直接在末尾添加元素的 add 方法,不用复制数组,直接 size ++ 就好,这个方法应该是我们最常使用的:
  5. ArrayList 又是如何删除数据的呢?
  Ctrl + F 找到 remove 方法,就这?和添加一个道理,也是复制数组
  举个例子,假设我们要删除数组的 index = 5 的元素,首先,我们会复制一遍源数组,然后把源数组中从 index + 1 = 6 的位置开始到数组末尾的元素,放到新数组的 index = 5 的位置上:
  也就是说 index = 5 的元素直接被覆盖掉了,给了你被删除的感觉。同样的,它的效率自然也是十分低下的 6. ArrayList 是线程安全的吗?不安全的表现
  ArrayList 和 LinkedList 都不是线程安全的,我们以在末尾添加元素的 add 方法为例,来看看 ArrayList 线程不安全的表现是啥:
  黄色框里的并不是一个原子操作,它由两步操作构成: elementData[size] = e; size = size + 1;
  在单线程执行这两条代码时,那当然没有任何问题,但是当多线程环境下执行时,可能就会发生 一个线程添加的值覆盖另一个线程添加的值 。举个例子: 假设 size = 0,我们要往这个数组的末尾添加元素 线程 A 开始添加一个元素,值为 A。此时它执行第一条操作,将 A 放在了数组 elementData 下标为 0 的位置上 接着线程 B 刚好也要开始添加一个值为 B 的元素,且走到了第一步操作。此时线程 B 获取到的 size 值依然为 0,于是它将 B 也放在了 elementData 下标为 0 的位置上 线程 A 开始增加 size 的值,size = 1 线程 B 开始增加 size 的值,size = 2
  这样,线程 A、B 都执行完毕后,理想的情况应该是 size = 2,elementData[0] = A,elementData[1] = B。而实际情况变成了 size = 2,elementData[0] = B(线程 B 覆盖了线程 A 的操作),下标 1 的位置上什么都没有。并且后续除非我们使用 set 方法修改下标为 1 的值,否则这个位置上将一直为 null,因为在末尾添加元素时将会从 size = 2 的位置上开始。
  上段代码验证下:
  结果和我们分析的一样:
  ArrayList 的线程安全版本是 Vector,它的实现很简单,就是把所有的方法统统加上 synchronized :
  既然它需要额外的开销来维持同步锁,所以理论上来说它要比 ArrayList 要慢。 7. 为什么线程不安全还要用它呢?
  因为在大多数场景中,查询的情况居多,不会涉及太频繁的增删。那如果真的涉及频繁的增删,可以使用LinkedList,底层链表实现,为增删而生。而如果你非得保证线程安全那就使用 Vector。当然实际开发中使用最多的还是 ArrayList,虽然线程不安全、增删效率低,但是查询效率高啊。

面试官问你期待工资多少时,该怎么回答?根据面试企业以及本身资历不同而有所区别。国企不同与私企和外企1。国企的工资是按照学历和资历决定的。博士研究僧本科(含海龟)在国企大概可以差20001000左右,海龟近年来看薪水优势奶粉要不要换着吃?您好,我是育婴师睿睿妈,很高兴回答您的问题。给宝宝选择奶粉时,相信家长们最注重的就是看奶粉的奶源和成分。不同品牌的奶粉成分不同,口味也不同,所以有些家长就想着,可以换着喝奶粉,让孩人到中年才懂普通人是没有真朋友的,你怎么看?是的,我非常赞同这个观点。俗话说得好穷在闹市无人问,富在深山有远亲。千百年来,人性没有改变。这句俗语放在今日今时依然适用。朋友给我讲过这样一个故事,她从小有个很好的发小,一起长大,阅读时经常看到未央一词,如雪落花未央。请问未央是何意?在中国文化中,未央是个古老而且出现频率很高的词汇。比如汉朝皇帝所居住的宫殿,叫做未央宫甚至在修辞上,未央宫时常成为汉宫的别称。并且,汉代宫人向皇帝太后等人请安的时候,也会说皇帝太后魔兽世界有哪些传说武器?谢邀。作为一家著名视频游戏制作和发行公司,暴雪公司塑造了一个拥有自己世界观的世界魔兽世界。在这个世界里,充满了英雄的传说。传说武器伴随着这些英雄流传了下来,成为了传说。那么废话不多为什么星际争霸2开局送12个兵?谢邀题主确定星际争霸2开局是送12个兵吗?在表述上好像有些许问题。笔者认为题主的意思,是在虚空之遗的早期,每个种族的初始农民数量从6个提升到12个了吧。众所周知,虚空之遗作为一个新为什么有些WIFI不能用万能钥匙搜索到?怎么才能破解邻居家的WIFI密码?在探讨这个问题前,我们先了解一下Wifi万能钥匙为何能够破解别人密码。严格来说,诸如Wifi万能钥匙,还有Wifi共享精灵这类的App,并不具备破解别人Wifi密码的能力,而是偷偷可以替代劳力士绿水鬼的手表有哪些?绿水鬼包括黑水鬼现在的行情就不用我多说了,被炒到超公价那么多还很难买到。所以我也在寻找水鬼的替代品。既然已经到了劳力士的档次,我想欧米伽海马系列就不用考虑了。还有宝珀的50噚,品牌每天化妆的人与不化妆的人在衰老后的区别是什么?小而美注重保养,每天化妆,真的会显得很年轻。因为化一个美美的妆真的会使心情变好,而心情好了呢,就会让我们的身体机能更年轻一些,是一个良性循环如果说每天化妆的人和不化妆的人相比,在衰0。6排量的车在日本畅销,为何国内不行?百公里仅3个油,尺寸小空间大,实用的KCar为啥国内不受欢迎?实际上就是因为KCAR在国内的天敌太多,根本不可能成为主销车型。如果去过日本,会发现大街小巷最多的车型就是KCAR,这在武汉,退休工资2500元够花吗?有住房,不得大病,两老5千元应该过生活还行。现在最大的不确定性是老人随着年龄增大肯定会生病,而医保旡论是看平诊或住院都是不小费用。而大部分老人都会生病。其次孤身老人年龄大了旡人照顾
真乃天人合一!被桃源这处神奇景观震撼到了摄影周桂成图说桃源黄石水库惊现人形岛奇观。由于连日高温少雨,桃源县黄石水库的水位下降到近年来最低。我们昨天在位于黄石水库尾水的茶源村航拍时,惊喜地发现了平时看不到的一些奇形怪状的小秋天的第一场旅行就来敬亭山吧,追寻你的诗和远方处暑之后,秋意渐浓正是迎秋赏景登高望远的好时节乘着初秋凉爽的风来敬亭山看一看季节轮替的美景来一场治愈又诗意的寻秋之旅吧!敬亭山初秋的敬亭山依然绿树成荫清凉舒适每个角落都有如诗如画的湖南阳光华天集团首秀湖南旅博会红网时刻新闻8月26日讯(记者龙真)8月25日,2022湖南文化旅游产业博览会在长沙国际会展中心举行,湖南阳光华天旅游发展集团携旗下两大文旅新品华天精选酒店3。0及湘绣风采独绣数字中共一大钩沉北京大学暑期旅行团南下上海中共一大会址纪念馆中还原了当年开会的场景近代中国,为了挽救日益严重的民族危机,无数中华儿女进行了多次艰难的探索。20世纪初,革命浪潮涌动,五四运动的发生使马克思主义与俄国十月革与默多克离婚后首露面,霍尔香烟在手笑容灿烂,身家已超20亿8月26日,66岁女明星杰瑞霍尔与91岁默多克离婚后首次露面,外媒以标题Itssmokewithoutire!透露霍尔的心情非常好。报道称,这是阳光明媚的一天,霍尔和女儿乘坐私人飞20220830人生大事最近有什么开心的事情么?如果没有,那是不是有什么不开心的事情?40岁的生日,我收到了一份大礼。然后有一天深夜,我和朋友说,我发现自己可能是真的老了,因为当很生气的时候,发现自己也发经典人生格言一你从80楼往下看,全是美景,但你从2楼往下看,全是垃圾。人若没有高度,看到的全是问题,人若没有格局,看到的全是鸡毛蒜皮。二一个人最可悲的就是为了别人的看法一味地改变自己,到了最后星汉灿烂刚收官就传来好消息,还有10集将播,播出时间也定了星汉灿烂可以说是当下大家最热议的电视剧了,这部剧集幽默风趣和演员美貌于一体,再加上考究的称呼和古代礼仪,深得观众喜爱,是当之无愧的古偶剧的天花板。而吴磊和赵露思的这对CP,大家也是整容是件锦上添花的事情,没有会拒绝完美的人生话说,在看过梦华录之后,小欧再一次被刘亦菲的颜值惊艳到,真的会反复爱上神仙姐姐啊!从金粉世家白秀珠到天龙八部王语嫣再到仙剑奇侠传赵灵儿刘亦菲,在无数人心中美得不可方物!话说神仙姐姐人生格言人生格言(89)人的一生靠德行,德才兼备造化深土地若是不肥厚,世间万物难承受做人若是无德行,做事往往会落空为人处世德为先,有德之人财运宽德是做人之修养,更能体现人福气小胜靠智大靠德光阴似水,待你如初陆小曼的烟火人生抄书打卡入口走进陆小曼的世界,你会发现她的前半生是肆意的,洒脱的,从未有传统之礼节,不喜约束,向往自由,对自己认定的爱情,有着坚贞的情缘。她的前半生,是富贵安逸的,如果没有认识到那