数组和链表,应该算是最基本的数据结构了吧。
最近在帮公司招人,这个问题我几乎是必问的,然而还是有很多同学答不上来呀,不禁让人唏嘘感慨,基础知识大家还是要多补补哦!

长度一百万的数组,get(0)和get(999999)性能有区别吗?
回答这个问题之前,先来看看数组和链表的一个区别,这样再回过头来看答案时,就会很清晰。

数组

数组(Array)是有序的元素序列。 若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组的各个元素的数字编号称为下标。数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按有序的形式组织起来的一种形式。 这些有序排列的同类数据元素的集合称为数组。

数组是一种最常用的线性数据结构,它的特点是内存连续,随机访问速度极快。

为什么数组随机访问速度极快?

数组的随机访问速度快,这主要依赖于连续的物理内存。因为内存是连续的,且每个元素占用的空间是等长的,所以不管数组多长,不管访问哪个元素,时间复杂度都是O(1),整个访问过程都只需要两次寻址。

数组的随机访问速度快,但是元素的插入和删除效率较低。
使用ArrayList,插入元素时,插入下标后的所有元素均需要往后移动一位。删除元素时,删除下标后的所有元素均需要向前移动一位。

链表

链表又细分为单向链表、双向链表、循环链表。

单向链表
每个节点维护一个额外的next属性,指向下一个节点。

双向链表
每个节点维护两个额外的属性prev和next,分别指向上一个节点和下一个节点。

循环链表
和双向链表一样,区别是头尾节点是相连的。

链表的优点就是数据的删除、添加速度很快,元素不用移动位置,只需要修改头尾指针的指向就可以了。

缺点是随机访问性能很差,为什么这么说呢?
当使用链表去访问下标数据时,流程大致如下,伪代码:

class Linked{Object data;Linked prev;Linked next;Object get(int index){Linked node = this;while (index > 0) {node = this.next;index--;}return node.data;}
}

链表没有下标,不像数组可以根据下标+步长直接算出元素的内存地址。链表需要通过访问next节点,不断的寻址,一个一个往下找,时间复杂度是O(n)。

数组和链表的性能对比

理论讲完了,该实战一下这两者的性能差距到底几何。

分别创建一百万长度的数组和链表,访问1万次最后的元素:

class Test{static int len = 1000000;public static void main(String[] args) {array();linked();}static void array(){List list = new ArrayList(len);for (int i = 0; i < len; i++) {list.add(i);}long t1 = System.currentTimeMillis();for (int i = 0; i < 10000; i++) {list.get(len-1);}long t2 = System.currentTimeMillis();System.out.println("数组耗时:"+(t2 - t1));}static void linked(){List list = new LinkedList();for (int i = 0; i < len; i++) {list.add(i);}long t1 = System.currentTimeMillis();for (int i = 0; i < 10000; i++) {list.get(len-1);}long t2 = System.currentTimeMillis();System.out.println("链表耗时:"+(t2 - t1));}
}

控制台输出:

What???说好的数组随机访问速度极快呢???怎么没体现出来???

哈哈,别着急,速度没区别是因为JDK对LinkedList.get()方法做了一些优化。

单纯的访问最后一个元素,数组和链表几乎没区别,都是两次寻址就能定位到元素。
知道原因后,代码改起来就简单了,访问中间的元素不就可以了嘛。

list.get(len-1)改为list.get(len/2),代码就不重复贴了,再次测试,结果如下:

看到没,效果是不是非常明显,数组耗时1毫秒,而链表用了整整23秒多,碾压式的胜利啊。
而且,链表的耗时会随着List长度的增加而增加,数组不管长度多少,性能都不会波动,原因前面已经说过了。


尾巴

长度一百万的数组,get(0)和get(999999)性能有区别吗?
相信通过这篇文章,我不说答案,大家也都知道了!!!

由于数组的内存是连续的,当需要创建长度很大的集合时,JVM很可能由于找不到一块很大的连续内存而导致内存溢出,这时可以考虑使用链表。


你可能感兴趣的文章:

  • AQS源码导读
  • 摊牌了,我要手写一个RPC
  • Java锁的膨胀过程以及一致性哈希对锁膨胀的影响
  • ThreadLocal源码解析
  • CMS与三色标记算法
  • 大白话理解可达性分析算法

长度一百万的数组,get(0)和get(999999)性能有区别吗?相关推荐

  1. C++如何定义一个长度超过一百万的数组

    在C++中若要设置长度大于1000000的数组,不能在函数内部声明,因为这样属于局部变量,存放在了栈上,容易造成内存溢出. 解决这个问题有两种办法: 1.将数组声明为全局变量: #include< ...

  2. 2022-12-14:给定一个正数n, 表示从0位置到n-1位置每个位置放着1件衣服 从0位置到n-1位置不仅有衣服,每个位置还摆着1个机器人 给定两个长度为n的数组,powers和rates pow

    2022-12-14:给定一个正数n, 表示从0位置到n-1位置每个位置放着1件衣服 从0位置到n-1位置不仅有衣服,每个位置还摆着1个机器人 给定两个长度为n的数组,powers和rates pow ...

  3. Java编程笔试时输入问题:如何输入固定长度、不定长度的一维数组?如何输入固定长度、不定长度的二维数组?

    Java编程笔试时输入问题: 如何输入固定长度.不定长度的一维数组? 如何输入固定长度.不定长度的二维数组? 如何将数组中的内容直接输出,不要中括号和逗号? 文章目录 ==Java编程笔试时输入问题= ...

  4. 函数中参数有数组时注意的小问题(不一定要传递数组长度,不用返回数组,可以在函数中改变数组元素值)

    函数中参数有数组时注意的小问题: 1.不一定要传递数组长度 2.不用返回数组,可以在函数中改变数组元素值 通过下面这个小例子来验证: #include<iostream> #include ...

  5. C语言中,当计算字符数组长度时,用sizeof 和strlen 的原理及两者的区别

    字符数组的长度计算:必须以终止符'/0'作为边界,但对字符数组赋值时,有两种方式: 1: 定义时用字符初始化 (1)char chs[7] = {'a', 'c', '0', 'z', '3','d' ...

  6. 1、leetcode209 长度最小的子数组

    leetcode209 长度最小的子数组 给定一个含有 n 个正整数的数组和一个正整数 target . 找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+ ...

  7. 209. Minimum Size Subarray Sum 长度最小的子数组

    Title 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组,并返回其长度.如果不存在符合条件的连续子数组,返回 0. **示例: ** 输入: ...

  8. 数组|leetcode209.长度最小的子数组

    给定一个含有 n 个正整数的数组和一个正整数 target . 找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, -, numsr-1, numsr] ...

  9. C语言变长数组data[0]【总结】

    C语言变长数组data[0][总结] 1.前言 今天在看代码中遇到一个结构中包含char data[0],第一次见到时感觉很奇怪,数组的长度怎么可以为零呢?于是上网搜索一下这样的用法的目的,发现在li ...

最新文章

  1. [NC23486]小A与小B 双向广搜
  2. python能做什么
  3. Focal Loss笔记
  4. (原创)无废话C#设计模式之十一:Composite
  5. PHP开发erp账号登陆问题,浪潮ERP软件E系列创建账套时提示“由于登陆不正确、请重新登陆” | 浪潮888博客...
  6. 根据输入的日期计算周次和月份
  7. torchvision学习之torchvision.datasets
  8. Python中threading的join和setDaemon的区别及用法[例子]
  9. 程序解析excel中的图片_Excel表格中链接图片操作方法,以后查看图片点点鼠标就可以了...
  10. 毅航产品—模拟载板I
  11. 数论学习-初等数论基础总览
  12. 联想昭阳E46A不能上网
  13. oracle优化distinct,oracle中使用group by优化distinct
  14. 论文笔记:NAOMI: Non-Autoregressive MultiresolutionSequence Imputation
  15. python停止线程_python线程之八:线程停止的3种方式,5个实例
  16. 一个刁刁的卡片样式广告轮播
  17. java微信app支付-支付结果通用通知
  18. 【计算机网络】边缘路由器 三种家庭接入网(光纤到户) DSL、HFC与PON
  19. SQL Server with as使用
  20. 【鸽子木 · 每日一题】级数求和(3月31日)

热门文章

  1. 小字辈 (25 分)
  2. hdu 5544 Ba Gua Zhen
  3. 托福高频真词List02 // 附阅读真题
  4. jsp+springboot使命必达跑腿接单网站系统 ssm
  5. 快餐连锁店Cava纽交所上市:首日大涨99% 市值49亿美元
  6. (8)雅思屠鸭第八天:听力中最重要的179个单词(必知必会)
  7. 利用计算机解决问题过程中找出已知,用计算机解决问题的过程.ppt
  8. 英语连接词~很全的版本!!!
  9. 简说Pinterest
  10. 机器学习【西瓜书/南瓜书】--- 第2章模型评估与选择(上)(学习笔记+公式推导)