java list主要实现_java容器-list的常用实现及原理
list是个一唯的线性存储容器。我们可以把它比喻成一个竹签子,你可以把山楂、橘子串在上面,也可以把鸡翅、羊肉串在上面。吃的时候你可以从头、尾或者中间任何地方下口。
我们下面着重介绍下两个常用的实现,ArrayList和LinkedList。
ArrayList
arraylist顾明思议就是通过数组这种数据结构实现的list。数组的实现可以让它从任意的位置读取数据,也可以把数据写入数组的任意位置,但由于数组需要指定长度,所以会有扩容的问题。
LinkedList
LinkedList是通过链表实现的list。它的每个节点都会存储前一个和后一个节点的指针,每个list还会存储头和尾两个指针,所以它不能直接读取指定位置,但不会有扩容的问题。
list的主要场景有4个,顺序写、随机写、顺序读和随机读,下面我们从这4个场景模拟分析下这两种实现的不同点。
1.顺序写
ArrayList
//我们先初始化一个ArrayList, 这时arraylist会帮我们初始化一个长度为10的数组
List list = new ArrayList();
因为数组初始化必须指定长度,所以我们创建ArrayList时就会创建一个定长数组。
//这时我们把调用add方法把1写入到list中
list.add("A");
因为arraylist会保存index,所以add方法只是把数组的index位赋值为A,index加1就可以了。
//这时我们把调用add方法把B写入到list中
list.add("B");
填加B也是同理
LinkedList
//我们先初始化一个LinkedList,初始化时LinkedList并不会做什么
List list = new LinkedList();
//这时我们把调用add方法把A写入到list中
list.add("A");
这时的linkedlist的头指针和尾指针同时指向A
//我们再调用add方法把B写入到list中
list.add("B");
当调用add方法时,因为尾指针指向的是A节点,所以把A节点的next节点指向B,同时尾节点指向B
2.随机写
Arraylist
//我们再调用add方法把C写入到list中
list.add(2, "C");
所以ArrayList的随机写时间复杂度为O(n)
LinkedList
//我们再调用add方法把C写入到list中
list.add(2, "C");
linkedlist虽然不需要做节点移动,但是他要通过A、B、D节点这样遍历的方式找打插入的位置,所以时间复杂度也为O(n)
3.顺序读
Arraylist
在访问arraylist中任意一个元素的时候,因为底层实现是数组,所以都可以直接读取,时间复杂度为O(1)。
LinkedList
使用迭代器读取linkedlist,迭代器会维护一个当前节点的指针,所以也不需要循环查找,时间复杂度为O(1)。
4.随机读
Arraylist
arraylist的随机读通过底层数组支持,时间复杂度为O(1)。
LinkedList
linkedlist的随机读则只能通过从头循环遍历的方式查找,所以时间复杂度为O(n)
5.ArrayList的扩容
数组因为长度固定,所以当数组已经存满的时候就需要扩容。
如图所示,当D插入到arraylist时,发现数组已满,这时arraylist就会新建一个数组,长度是原来的2倍,并把原数组的数据移动到新数组,再把D插入到新数组中。
最后我们对比下这两个实现的时间复杂度。
时间复杂度
ArrayList
LinkedList
顺序写
O(1)
O(1)
随机写
O(n)
O(n)
顺序读
O(1)
O(1)
随机读
O(1)
O(n)
总结下我们应该如果选择
如果数据大小固定,需要随机读取使用ArrayList
如果数据大小不确定,不需要随机读取,使用LinkedList
java list主要实现_java容器-list的常用实现及原理相关推荐
- java中的集合_Java 集合介绍,常用集合类
JAVA 集合 在处理数据的过程中经常会需要一个容器来存储某一类型的数据,Java 中的数组就是这样一种容器.但 Java 中的数组有其局限性,定义后的数组长度不可变,超出数组长度后就不能再存放数据了 ...
- java 建树源码_Java实现的二叉树常用操作【前序建树,前中后递归非递归遍历及层序遍历】...
import java.util.ArrayDeque; import java.util.Queue; import java.util.Stack; //二叉树的建树,前中后 递归非递归遍历 层序 ...
- java dump分析工具_java性能分析与常用工具
本次源码已放在Github:https://github.com/nateshao/jvm-tuning 个人博客 https://nateshao.gitee.io http://www.nates ...
- java 多线程间通讯_JAVA多线程间通讯常用实现方法解析
如何实现线程间通讯,有如下三种方法: 1.使用Semaphore (信号量)类来控制线程的等待和释放 功能:三个线程 a .b .c 并发运行,b,c 需要 a 线程的数据怎么实现 分析:考虑到多线程 ...
- java 实现 web 客户端_Java web客户端和服务器端交互的原理
Java web客户端和服务器端交互的原理 其实HTTP客户端和服务器端的交互原理很简单:即先是浏览器和服务器端建立Socket无状态连接,也就是短连接,然后通过IO流进行报文信息(这个报文是严格遵循 ...
- java regex match 替换_java正则表达式四种常用的处理方式(匹配、分割、替代、获取)...
java 正则表达式高级篇,介绍四种常用的处理方式:匹配.分割.替代.获取,具体内容如下 package test; import java.util.regex.Matcher; import ja ...
- java语言冒泡排序法_Java实现八个常用的排序算法:插入排序、冒泡排序、选择排序、希尔排序等...
本文实现了八个常用的排序算法:插入排序.冒泡排序.选择排序.希尔排序 .快速排序.归并排序.堆排序和LST基数排序 首先是EightAlgorithms.java文件,代码如下: import jav ...
- java date类 时区_Java时区转换及Date类实现原理解析
这篇文章主要介绍了Java时区转换及Date类实现原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.时区的说明 地球表面按经线从东到西,被 ...
- java增强for循环_Java中增强for循环的实现原理和坑详解
前言 引入增强for循环的原因:在JDK5以前的版本中,遍历数组或集合中的元素,需要先获得数组的长度或集合的迭代器,比较麻烦. JDK5中定义了一种新的语法----增强for循环,以简化此类操作.增强 ...
最新文章
- python 字典 的pop 方法
- 计算机初级学哪个公需课,西安职称评审申报你遇到以下问题了吗?
- lnmp/nginx系统真正有效的图片防盗链完整设置详解
- opencv+dlib人脸关键点检测cpp版
- openlayers基础(一)——Map
- CSS-非常有用的css变量
- QIPAIFANS网站程序【2013最新版】
- 7-68 求整数段和 (15 分)
- 为什么我们没有选择Rust?
- 加州理工学院公开课:机器学习与数据挖掘_过拟化
- 打开你企业发展之门的钥匙
- c语言tc2.0编译器下载,c语言编译器|c语言编译器(wintc)_绿茶手机网
- win2003服务器360修复漏洞打不开网页,win7电脑使用360浏览器打不开网页的有效恢复方法...
- 进击的Libra:路在何方?中国应如何应对?
- 教你如何关闭Win7视频预览节约资源
- 2-3、迭代法计算定积分
- excel柱形图/条形图怎能给正负值填充不同的颜色
- python绘制饼图
- 假如生活欺骗了你-普希金
- 基于VUE + Echarts 实现可视化数据大屏旅游大数据