Java进阶(List)——面试时List常见问题解读 结合源码分析

在这里插入图片描述

前言

List、Set、HashMap作为Java中常用的集合,需要深入认识其原理和特性。

本篇博客介绍常见的关于Java中List集合的面试问题,结合源码分析题目背后的知识点。

关于的Set的博客文章如下:

  • Java进阶(Set)——面试时Set常见问题解读 & 结合源码分析

关于HaseMap的博客文章如下:

  • Java进阶(HashMap)——面试时HashMap常见问题解读 & 结合源码分析
  • Java进阶(ConcurrentHashMap)——面试时ConcurrentHashMap常见问题解读 & 结合源码分析 & 多线程CAS比较并交换 初识

其他相关的List的文章合集如下:

  • 手动实现ArrayList & 源码的初步理解分析 & 数组插入数据和删除数据的问题

  • Java学数据结构(1)——抽象数据类型ADT & 表List、栈Stack和队列Qeue

目录

  • 前言
  • 引出
  • ArrayList 如何扩容的?/ArrayList的大小是如何自动增加的?
    • 1.add添加第一个元素
    • 2.添加第11个元素时
  • 如何复制某个ArrayList到另一个Arraylist中去?
    • 厘清概念:深浅拷贝
    • 复制的方法
  • 在索引中ArrayList的增加或者删除某个对象的运行过程?效率很低吗?解释一下为什么?
    • 效率确实低
    • 源码arraycopy方法
  • 现在我有一个很大的数组需要拷贝,原数组大小是 5k,请问如何快速拷贝?
  • 如何获得一个线程安全的ArrayList集合?
    • Collections.synchronizedList
    • 源码分析
  • LinkedList 和 ArrayList 该如何选择?
    • 选择原则
    • LinkedList源码node节点
  • Vector 集合
  • 总结

引出


1.ArrayList如何扩容,1.5倍;
2.ArrayList如何拷贝,深拷贝,浅拷贝;
3.ArrayList的增加或者删除效率低,arraycopy方法;
4.指定长度创建ArrayList对象,避免频繁扩容;
5.线程安全的ArrayList集合:Collections.synchronizedList;
6.LinkedList 和 ArrayList 该如何选择:ArrayList增删效率低,查询效率高;LinkedList 查询效率低,增删效率高
7.Vector 集合和 ArrayList 区别:Vector扩容机制为原始的2倍,线程安全;

ArrayList 如何扩容的?/ArrayList的大小是如何自动增加的?

ArrayList初始化的时候,若没有给定长度,则默认调用无参构造

在这里插入图片描述

此处elelmentData为ArrayList底层数组,后面DEFAULTCAPACITY_EMPTY_ELEMENTDATA 为常量数组初值为空,即长度为0

在这里插入图片描述

1.add添加第一个元素

当执行add方法添加第一个元素时,执行下面的代码

在这里插入图片描述

此处涉及到两条代码:

  • ensureCapacityInternal方法内会调用calculateCapacity方法,此处才是赋予数组长度为10

ensureCapacityInternal 方法

在这里插入图片描述

calculateCapacity方法

在这里插入图片描述

private static int calculateCapacity(Object[] elementData, int minCapacity) {//如果数组是空的if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//返回数组的容量,DEFAULT_CAPACITY=10return Math.max(DEFAULT_CAPACITY, minCapacity);}return minCapacity;}

此时集合可以添加默认的10个元素

2.添加第11个元素时

当添加第11个元素时,ensureExplicitCapacity方法中,minCapacity为11,而原数组长度为10,所以if结构进入grow方法-扩容核心方法

ensureExplicitCapacity方法

在这里插入图片描述

grow方法-扩容核心方法

在这里插入图片描述

private void grow(int minCapacity) {// overflow-conscious code//把旧的长度赋值给oldCapacityint oldCapacity = elementData.length;//新的长度就=旧的长度*1.5int newCapacity = oldCapacity + (oldCapacity >> 1);if (newCapacity - minCapacity < 0)newCapacity = minCapacity;if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);// minCapacity is usually close to size, so this is a win://按照新的长度复制出一个新的数组elementData = Arrays.copyOf(elementData, newCapacity);}
  • oldCapacity赋值为原数组长度,为10 ,newCapacity赋值为原长度1.5倍,即15

  • 调用复制数组方法,将之前的数组复制到新的数组中,并将需要添加的元素加到数组最后一位,完成扩容!

如何复制某个ArrayList到另一个Arraylist中去?

重写clone方法,ArrayList克隆

在这里插入图片描述

厘清概念:深浅拷贝

Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化

在这里插入图片描述

浅拷贝:虽然返回一个元素一样的ArrayList,复制的是元素的引用,即其中一个改变了元素,另一个也会跟着改变

两个集合中间存储了同一份元素的引用

例如:

深拷贝:重写clone方法,利用迭代器iterator或遍历集合,重新创建引用对象,逐个添加

例如:

在这里插入图片描述

复制的方法

在这里插入图片描述

list.clone()

在这里插入图片描述

clone.addALl(list);

在这里插入图片描述

Collections.copy(clone,list);

在这里插入图片描述

在索引中ArrayList的增加或者删除某个对象的运行过程?效率很低吗?解释一下为什么?

效率确实低

效率是很低的,因为ArrayList无论是增加或者删除某个对象,我们都要通过对数组中的元素进行移位来实现。

  • 增加元素时,我们要把要增加位置及以后的所有元素都往后移一位,先腾出一个空间,然后再进行添加。
  • 删除某个元素时,我们也要把删除位置以后的元素全部元素往前挪一位,通过覆盖的方式来删除。

而这种移位就需要不断的arraycopy,是很耗时间的,所以效率自然也很低。

源码arraycopy方法

增加元素时

在这里插入图片描述

删除元素时

在这里插入图片描述

现在我有一个很大的数组需要拷贝,原数组大小是 5k,请问如何快速拷贝?

指定长度创建ArrayList对象,避免频繁扩容

如何获得一个线程安全的ArrayList集合?

Collections.synchronizedList

List<Object> datas = Collections.synchronizedList(new ArrayList<>());

源码分析

在这里插入图片描述

从源码可以看到集合操作都加了synchronized 关键字,保证了在同一时刻,数组和链表只会被一个线程所修改。

LinkedList 和 ArrayList 该如何选择?

选择原则

  • ArrayList 底层为数组,在增加和删除元素时会频繁的调用arraycopy,所以查询效率高,增删效率低
  • LinkedList 底层为链表,故查询效率低,但增删效率高。

LinkedList源码node节点

在这里插入图片描述

  • item 为当前元素
  • next指向下一个元素,若为最后一个则为null
  • prev指向上一个元素,若为第一个则为null

在这里插入图片描述

Vector 集合

  1. vector 和 ArrayList 基本一样
  2. 区别在于 vector扩容机制为原始的2倍,ArrayList为之前的1.5倍
  3. vector 是线程安全的,ArrayList是非线程安全的

在这里插入图片描述


总结

1.ArrayList如何扩容,1.5倍;
2.ArrayList如何拷贝,深拷贝,浅拷贝;
3.ArrayList的增加或者删除效率低,arraycopy方法;
4.指定长度创建ArrayList对象,避免频繁扩容;
5.线程安全的ArrayList集合:Collections.synchronizedList;
6.LinkedList 和 ArrayList 该如何选择:ArrayList增删效率低,查询效率高;LinkedList 查询效率低,增删效率高
7.Vector 集合和 ArrayList 区别:Vector扩容机制为原始的2倍,线程安全;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/155008.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C语言_题库】C语言:编写一个程序,输入一组字符串,将字符串中的小写字母转换为大写字母,其它字符不变,并输出。

把键盘输入的一行字符串的小写字母转换成大写字母,其余字符不变,进行输出,直到遇到回车为止。 具体说明 【问题描述】 从键盘输入一行英文字符串,把所有小写字母变成大写字母,其他字母和字符保持不变。 【输入形式】 输入一行字符串,含大小写。 【输出形式】 输出大写字…

linux后台运行python脚本

前言 我们在运行程序时&#xff0c;有的程序花费时间较多&#xff0c;但我们总不能一直看着程序运行&#xff0c;所以我在这里记录一下&#xff0c;Linux服务器如何后台运行我们的脚本程序 实现后台运行程序 我们登录到服务器&#xff0c;切换至目录到我们所要运行的程序下 …

弱覆盖栅格图层制作

栅格边界生成及图层制作 栅格边界polygon生成 提取的弱覆盖栅格数据中包含了栅格中心经度和栅格中心维度&#xff0c;我们根据栅格中心经纬度生成对应的栅格边界POLYGON&#xff08;20米*40米&#xff09; 计算公式&#xff1a;polygon(栅格中心经度-0.00017 栅格中心纬度0.00…

自主查询成绩

今天我们来揭秘如何制作成绩查询系统&#xff0c;让学生可以自行查看成绩&#xff01; 成绩查询系统可以帮助学生和老师轻松管理、发布、查看成绩。无论是期中考试、期末考试&#xff0c;作业查询还是平时的课堂表现&#xff0c;都可以通过成绩查询系统来及时掌握。 让我们一起…

qt-gui

C常用GUI开发框架Qt&#xff0c;开始支持Python 2018-12-24 12:49 C的GUI接口开发框架Qt宣布&#xff0c;在5.12版本中开始支持Python&#xff0c;Python开发人员现在可以使用所有的Qt API&#xff0c;目前仍在技术预览版的阶段&#xff0c;但官方也承诺&#xff0c;正式版将…

4.2 SSAO算法 屏幕空间环境光遮蔽

一、SSAO介绍 AO 环境光遮蔽&#xff0c;全程Ambient Occlustion&#xff0c;是计算机图形学中的一种着色和渲染技术&#xff0c;模拟光线到达物体能力的粗略的全局方法&#xff0c;描述光线到达物体表面的能力。 SSAO 屏幕空间环境光遮蔽&#xff0c;全程 Screen Space Amb…

thinkphp链接mqtt服务器,然后在订阅下发布消息

cmd打开项目根目录&#xff0c;安装插件&#xff0c;执行下面的命令 composer require php-mqtt/client执行完成之后会在vendor 目录下有php-mqtt 文件 然后在你的 extend文件下 新建mqtt文件 在文件中新建 Mqtt.php 下面是代码 <?php /** S: * Name: 控制器: * Autho…

真心话坦白局系统源码

它具有匿名信息的神秘感 但又会给你一点小提示 能让你有无限挖掘下去的好奇感 也能让你说出那些不敢说出口的话 敢来一场坦白局吗&#xff01; 坦白局这个功能类似于悄悄话&#xff0c;只不过是匿名的悄悄话。 有时候我们有些话是开不了口的&#xff0c;坦白局给了我们一个…

图的深度优先遍历的六种应用附Java代码

目录 无向图的连通分量个数 单纯求出了连通分量个数 能具体返回哪几个点是同一个连通分量 路径问题 单源路径问题 从某个顶点到另一个顶点的路径问题 检测无向图中的环 二分图的检测 无向图的连通分量个数 单纯求出了连通分量个数 import java.util.ArrayList;publi…

数据库分库分表的原则

目录 1、数据库分库分表是什么 2、为什么要对数据库分库分表 3、何时选择分库分表 4、⭐分库分表遵循的原则 5、分库分表的方式 6、数据存放在表和库中的规则&#xff08;算法&#xff09; 7、分库分表的架构模式 8、分库分表的问题 小结 1、数据库分库分表是什么 数…

Simulink的To Workspace

To Workspace模块将Simulink产生的数据存储到matlab的工作区。 用To Workspace模块中的数据进行绘图。 参见Matlab/simulink/simscape multibody-to wotkspace模块使用_to workspace模块_五VV的博客-CSDN博客

AGRCZO-A-20/210先导比例减压阀控制器

AGRCZO-A-10/100、AGRCZO-A-20/210、AGRCZO-A-10/50、AGRCZO-A-20/350、AGRCZO-A-10/315、AGRCZO-A-20/100数字型比例减压阀&#xff0c;先导式&#xff0c;用于压力开环控制。A型&#xff0c;与分体式放大器配合使用AEB型&#xff0c;带基本型集成式数字放大器&#xff0c;模拟…