数组和链表是数据结构中最基本的部分。

数组

在java中,数组定义为一种基本类型,其可以通过下标获取到对应位置的数据。那么这种结构的数据,在内存中是怎么存放的呢?

数组在内存中是一段连续的存储单元,每个数据依次放在每个单元中。

分析这种结构,我们可以得出以下几个结论:

  • 创建一个数组,必须声明其长度,以在内存中寻找合适的一段连续存储单元。这也意味着数组的大小是固定的,我们无法动态调整其大小。
  • 想要获取数组中第i个元素,其时间复杂度是 O(1),因为可以根据其地址直接找到它。同理修改也是。
  • 数组对查询表现一般,要想查找一个元素,需要遍历,时间复杂度为O(n)。
  • 因为地址连续,想要在数组中插入一个元素是复杂的,因为从插入位置起,后边的所有元素都需要向后移动一位。同理删除也是,只是移动方向为向前。并且,当数组存满时,就无法继续插入了。
  • 因为数组要占据一整块内存,有可能产生许多的碎片,也可能因为找不到合适的内存块,而导致存储失败。

总结起来就是:数组大小固定,查找迅速,增删复杂,需要完整的内存块,容易产生碎片。

链表

链表是一种离散存储结构,其在内存中存储不是连续的,每个数据元素都通过一个指针指向其下一个元素的地址。根据指针域的不同,链表又分为单链表、双向链表、循环链表等,这里我们只分析单链表。示意图如下所示:

分析这种结构,我们可以得出以下几个结论:

  • 声明一个链表时,不需要知道其长度,也不需要连续的内存块,所以其大小可以动态调整。
  • 链表的每个元素都分为数据域和指针域,前者是实际存储的数据,后者则指向下一个元素的地址。和数组相比,每个元素需要占用的内存更大了。
  • 要获取链表的第 i 个元素变得复杂,因为其地址存放在它上一个元素的指针域里,所以只能从第一个元素起,进行 i 次操作。同理修改也是。
  • 链表对查询表现也一般,需要遍历,时间复杂度为O(n)。
  • 增加与删除一个元素更方便了,因为没有对内存地址的限制,我们只需要在对应节点合理处理下指针域的值,就可以把一个元素插入链表或者从链表删除。
  • 链表对内存的要求很小,只要能够存储下一个数据元素的内存块都可以使用,因此不会造成碎片化。

总结起来就是:大小可以动态调整,增删迅速,查找较慢,数据元素所占内存略多,不需要整块内存块,不会造成碎片化。

数组与链表的选择

通过以上分析,数组和链表对我们影响最大的几点区别在于:

  • 数组按位置查找迅速,链表增删方便
  • 数组是固定大小,链表可以随时扩充与缩减
  • 链表每个元素占据内存略多于数组
  • 数组和链表在查询方面表现都比较一般,耗时较长

在数据量很小,内容基本固定时,我们选择何种数据结构的影响并不大。

但当数据量较大时,如果我们需要对数据进行频繁的插入删除,我们应该选择链表,如果我们需要频繁的获取某个位置的元素,我们应该选择数组。

数组与链表并没有明确的优劣之分,根据不同的使用场景进行不同的选择,才是这两种结构使用的最佳方式。

源码:Java集合源码之:数组与链表(一)的更多相关文章

  1. Java集合源码分析(四)Vector<E>

    Vector<E>简介 Vector也是基于数组实现的,是一个动态数组,其容量能自动增长. Vector是JDK1.0引入了,它的很多实现方法都加入了同步语句,因此是线程安全的(其实也只是 ...

  2. Java集合源码分析(三)LinkedList

    LinkedList简介 LinkedList是基于双向循环链表(从源码中可以很容易看出)实现的,除了可以当做链表来操作外,它还可以当做栈.队列和双端队列来使用. LinkedList同样是非线程安全 ...

  3. Java集合源码分析(二)ArrayList

    ArrayList简介 ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存. ArrayList不是线程安全的,只能用在单线程环境下,多线 ...

  4. Java集合源码学习(一)集合框架概览

    >>集合框架 Java集合框架包含了大部分Java开发中用到的数据结构,主要包括List列表.Set集合.Map映射.迭代器(Iterator.Enumeration).工具类(Array ...

  5. java集合源码分析(三):ArrayList

    概述 在前文:java集合源码分析(二):List与AbstractList 和 java集合源码分析(一):Collection 与 AbstractCollection 中,我们大致了解了从 Co ...

  6. java集合源码分析(六):HashMap

    概述 HashMap 是 Map 接口下一个线程不安全的,基于哈希表的实现类.由于他解决哈希冲突的方式是分离链表法,也就是拉链法,因此他的数据结构是数组+链表,在 JDK8 以后,当哈希冲突严重时,H ...

  7. Java 集合源码分析(一)HashMap

    目录 Java 集合源码分析(一)HashMap 1. 概要 2. JDK 7 的 HashMap 3. JDK 1.8 的 HashMap 4. Hashtable 5. JDK 1.7 的 Con ...

  8. java集合源码分析几篇文章

    java集合源码解析https://blog.csdn.net/ns_code/article/category/2362915

  9. Java集合源码学习(四)HashMap分析

    ArrayList.LinkedList和HashMap的源码是一起看的,横向对比吧,感觉对这三种数据结构的理解加深了很多. >>数组.链表和哈希表结构 数据结构中有数组和链表来实现对数据 ...

随机推荐

  1. Linux .vimrc 设置项

    Linux 下,.vimrc 有两个.一个是全局使用的(/etc/vimrc),另一个是个人使用的(~/.vimrc). 大部分的情况下,我们只需要设置自己目录下的.vimrc 即可. # vim ~ ...

  2. Python *Mix_w4

    1.什么是列表(list) 列表是一个可变的数据类型 列表由[ ]来表示,每一项元素使用逗号隔开.列表什么都能装,能装对象的对象. 列表可以装大量的数据,列表能装所有数据类型 2.列表的索引和切片 列 ...

  3. .net core WebApi Monitor实现并发同步

    在.net中,还可以使用Monitor实现线程并发同步.Monitor类是纯托管且完全可移植,并且可能会在操作系统资源需求方面更加高效. Monitor的锁对象尽可能使用引用对象,如果是字符串或值对象 ...

  4. python异常处理机制

    python有五种异常处理机制,分别是 1.默认异常处理器. 如果我们没有对异常进行任何预防,那么程序在执行过程中发生异常就会中断程序,调用python默认的异常处理器,并在终端输出异常信息,如图所示 ...

  5. Java语法基础学习DayFourteen(IO)

    一.java.io.FIle类 1.特点 (1)凡是与输入.输出相关的类.接口等都定义在java.io包下. (2)File是一个类,使用构造器创建对象,此对象对应一个文件(.txt .avi .do ...

  6. vue学习笔记 - 篇2

    1.借助Vue.extend()方法创建组件 注意点 var Aaa = Vue.extend({ template: "<h1>这是标题</h1>" }) ...

  7. Spring 源码学习(1)—— 容器的基本实现

    最近在读Spring的源码,参考的是郝佳的<Spring源码深度解析>,这里把一些学习心得分享一下,总结的地方可能还有一些不完善,希望大家指教 IoC(控制反转)是Spring的特性之一, ...

  8. 初始Java

  9. gzip 所使用压缩算法的基本原理(选摘)

    摘自:http://blog.csdn.net/ghevinn/article/details/45747465  gzip 所使用压缩算法的基本原理 gzip 对于要压缩的文件,首先使用LZ77算法 ...

  10. 使用vue+koa实现一个简单的图书小程序(1)

    这个系列的博客用来记录我开发时候遇到的问题以及学习到的知识 边做边学: 前后端分离,高内聚低耦合小程序端使用了mpvue 内部使用了vuejs的语法 来做整个小程序的渲染层 后端使用的是koa2搭建一 ...