JavaSE基础(五)——数组的概念
前言
数组算是Java语言基础中为数不多的比较贴近计算机底层的知识点之一吧,关于数组这里记录的可能并不是很工整,但是我会尽量把现阶段大家能理解的东西都记录下来,尝试着学吧,加油!
数组
定义
数组现在不单单只能存放数字,那为什么还叫做数组呢?从最开始的时候,我们的计算机利用纸带来记录数据,也就是我们常说的二进制,后来出现高低电平表示的二进制数据替代了之前的纸带记录方式,然后我们通过输入二进制指令来操作计算机。由此可见,最早的时候数组的确是只用来存放数字的概念,直到后来出现数组的实质技术,并将所有能输入到计算机中的字符都可以存放在数组中。
数组其实就是相同类型的数据的有序集合,其中每一个数据都被成为数组元素,每个数组元素可以通过对应的数组下标来访问。
数组是一种数据结构,至于什么是数据结构大家可以先不用深究,暂时理解为:数据在计算机中的存储方式以及数据与数据之间的逻辑关系的表示即为数据结构。
要点
数组的定义方式如下:
数据类型[] 数组名 = new 数据类型[n];
【注】:学过C语言的同学可能对于数组的定义方式不太一样,不单单是关于对象方面,C语言会把中括号(方括号)放在数组名后,其实在Java中也可以这样写,二者没有任何区别,只是Java官方对于数组的定义是上述格式,入乡随俗,我们在Java中也这么写就好了。
在学习数组之前还有一个知识点要注意:刚才说过数组的访问通过索引(数组下标)的方式来访问,而索引(数组下标)是从0开始的,计算机就是这么定义的,大家记住。
至于什么是索引(数组下标),我们可以理解为:数组相同类型数据的有序集合,如果使用存放数据的地址空间的地址来访问,对于程序员来说十分不友好,所以我们采用了一种相对位置来记录数据的存放地址,这样在使用的时候会方便很多(其底层逻辑很复杂,后期会专门整理一个数据结构系列博客,在其中会详细讲解)。
int[] arrs = new int[10];
for(int i = 0; i < 10; i ++){
arrs[i] = i + 1;
}
- 如果我们并没有对于所有的数组元素赋值的话,那么没有被赋值的位置是当前数据类型的默认值,比如:int的默认值为0;String的默认值为null;
- 如果赋值数据的个数超过了数组的长度,则会出现数组下标越界异常;
- 数组的长度可以使用arrs.length 来获取。
内存分析
很多人在使用数组的时候会出现内存溢出、数组下标异常等情况,好多初学者对这种问题一知半解。针对这一点,在这里简单介绍一下内存(不会很详细,后期记录高阶知识点的时候,会有详细说明)。
首先说一下什么是内存,在计算机组成原理那篇笔记里可能讲过(忘了讲没讲过了,懒得去看),任何程序安装在电脑上,都是放在硬盘中,即辅存。比如lol、QQ等软件都安装在辅存中,如果我们需要运行他们时,计算机就会把运行软件所需要的相关程序调入到内存当中, 这样才可以运行相关软件(所以有的时候我们玩游戏需要内存大一点的电脑,内存太小放不下呀)。
在Java中,内存主要分为以下几类:
- 堆内存;
- 栈内存;
- 方法区(缓冲池或常量池,这个讲到String类的时候会有详细讲解,本篇笔记不会涉及)。
下面说到的知识点可能涉及到对象,初学者们可以先看我另一篇笔记稍微了解一下:
第一章 Java类与对象(一)
首先来说一下堆内存,堆内存是存放数组和对象的,也就是说通常情况下,我们创建的对象也就是常说的new出来的对象都放在堆内存,这才是我们常说的数据所在的地址空间。
栈内存是用来存放我们定义的变量名(数据的引用)的,从这里科普一个小知识点,我们在代码中对数据操作都写成对变量名的操作,程序会自动通过变量名所指向的地址空间对数据进行操作,这个行为对程序员来说是透明的。同时,我们也会将对象的引用放在栈内存中。对于对象不太了解的同学先看一看上面那个链接,后期会仔细讲解。
方法区中存放的是我们在类中写的一些方法,涉及到对象,面向对象时再讲。
数组定义的内存分析
接下来说明一下数组的创建,当我们创建数组空间的时候,执行逻辑是:
int[] arrs = new int[10];
- 首先在堆内存中开辟十个长度为int字节数的物理空间;
- 然后在栈内存中定义一个数组的引用,并将堆内存中开辟的空间中数组头的物理地址赋值给引用(可以理解为指针指向数组头部的物理空间);
- 数组在定义的时候长度便已经固定了,即数组为定长的;
- 数组的创建有两种:静态初始化、动态初始化,上述代码为动态初始化。
静态初始化与动态初始化
首先来看一下动态初始化与静态初始化在代码中的不同:
int[] arrs1 = {1,2,3};
int[] arrs2 = new int[3];
a[0]=1;
a[2]=3;
内存分析
数组是引用类型,所以数组中的元素相当于类的实例变量(对象),所以数组在分配空间时自动在堆内存中开辟相应的物理空间;
引用类型同样涉及面向对象的概念,大家只要知道引用类型的一些小概念就好,我会尽快更新到面向对象的博客。
上面说过数组在定义后的长度是固定的,所以我们在申请超过数组长度的数据时就会出现数组下标越界异常;这一点大家可以试一试,长度为定长是不允许动态更改的。
总结
总结一下数组需要注意的要点:
- 数组长度定长,一旦创建则长度不能改变,如果长度不够,那就新建一个数组,把数据复制进去(C语言的同学可能还需要将空间释放,Java有自己的垃圾回收机制,可以自动回收垃圾,不过也存在一些问题,属于人工智障级别的,后期会单独在杂谈系列中讲解);
- 数组中存放的元素类型必须是与数组类型一致的,不能出现混合类型;
- 数组中的元素可以是任何数据类型,包括基本类型和引用类型(开篇说过数组就是一种数据结构,所以只要是计算机可以识别的数据,我们都可以通过数据结构的逻辑和概念对其进行操作);
- 数组的下标从0开始,即数组最后一个元素的下标为数组长度减一;
- 数组的变量属于引用类型,数组可以看做是对象,每个数据元素可以理解为成员变量;
本篇笔记记录一下数据的相关概念,因为初学者在数组这边卡的比较严重,所以大家多理解一下,下一篇笔记来对数组进行实操。
|