数组
- 定义1:用于存储数据的长度固定的容器,保证多个数据的数据类型要一致。
- 定义2:相同的数据类型的元素按一定顺序排列的集合,就是把有限个类型相同的变量用一个名字命名,以便于统一管理他们,然后用编号区分,这个名字成为数组名;编号为数组下标或索引。组成数组的各个变量称为数组的元素;数组中元素的个数称为数组的长度。
- 数组特点:
(1)长度一旦确定就不能更改;
(2)创建数组时会在内存中开辟一整块连续的空间;
(3)存取元素的速度快,因为可以通过数组下标直接定位到任意一个元素。 - 数组分类:
1、按维度分:
(1)一维数组:存储一组数据;
(2)二维数组:存储多组数据,相当于二维表,一行代表一组数据,且该二维数组每一行的长度不要求一样。
注意:一维数组的元素是变量;二维数组的元素是数组。
2、按元素类型分
(1)基本数据类型的元素:存储数据值
(2)引用数据类型的元素:存储对象(本质上是存储对象的首地址)
注意:无论数组的元素是基本数据类型还是引用数据类型,数组本身都是引用数据类型。
一维数组
定义格式
共有两种定义格式,推荐第一种,因为可以直接知道此为一维数组。如图所示
数组声明
声明步骤:
(1)确定数组的维度:在java中数组的标点符号是[],[]表示一维;而[][]表示二维;
(2)确定数组的元素类型:即创建的数组容器可以存储什么数据类型的数据。元素的类型可以是任意的java的数据类型;
(3)确定数组名:就是代表某个数组的标识符,数组名其实也是变量名,按照变量的命名规范来命名。数组是一个引用数据类型的变量,因为它代表一组数据。
数组初始化并赋值
注意
(1)数组必须初始化才能使用;
(2)数组必须在初始化时给出长度且长度不能再改变(数组定长);
(3)初始化相当于赋值,若不初始化就相当于没有赋值,就无法使用,系统就会报错。
动态初始化数组
定义格式:new代表动态初始化数组,5代表初始化的数组的长度。
方式一:数组声明和初始化最好是一起完成的,否则运行会出错。------在一行之内完成。
方式二:先声明,然后再进行初始化。------可以断成两行完成。
注意:以上两种方式只是动态申请了五个存储空间,并没有存储元素。
动态初始化赋值方式
只有一种赋值方式:一个一个赋值
访问数组元素
- 数组的下标有合法下标和非法下标的区分。
合法下标:0到数组长度-1的部分。即[0,n-1],n为数组长度。
非法下标:除合法下标以外全都是非法下标。 - 访问方式:数组名[下标]
静态初始化数组
- 定义格式:声明时直接初始化并赋值。
方式一:声明、初始化和赋值在一行之内完成
方式二:
(1)一行完成
(2)断成两行完成即声明时先不赋值,后续使用时在进行赋值。
- 特点:
(1)在初始化数组的同时为每一个元素赋值;
(2)打括号中元素的个数即为数组长度。
动态初始化和静态初始化的选择
(1)若创建数组是为了保存将来会产生的新数据则使用动态初始化数组;
(2)若数组现有数据是固定的且不会产生新数据则使用静态初始化数组;
(3)具体怎么选择根据特定场景特定情况进行选择。
数组元素类型对应的元素默认初始值
即你不给数组进行赋值,数组元素也有默认初始值。此处以int类型为例进行说明。
数组内存分析
变量与数组的不同
以上代码变量输出特点与数组输出特点不同的原因为:
- 针对变量来说,申请空间直接是在栈中申请,且元素也保存在栈中;
- 针对数组来说,int[] num1是声明变量,变量在栈里保存;而new关键字开辟的内存空间都在堆里。数组名中存的是在堆里所开辟的内存空间的首地址(即存了一串来连续存储空间的首元素地址)。所以num1和num2指的是堆里相同的内存空间地址。
- 由于以上原因,所以在对数组num1进行赋值或者更改值时,num2也会随着改变;或者对数组num2进行赋值或者更改值时,num1也会随着改变。
程序执行流程
(1)main方法进入方法栈执行;
(2)创建数组,JVM会在堆内存中开辟空间,存储数组;
(3)数组在内存中会有自己的内存地址,以十六进制数表示,如图所示打印出arr(即数组)。
程序分析
代码结果解析:
数据组num1(num2)中有三个元素,默认值为0;
JVM将数组的内存首地址赋值给引用类型变量arr(即数组);
变量arr保存的是数组内存中的地址而不是一个具体数值,因此称为引用数据类型
注意
- arr中存储的是数组的首地址,但是因为数组是引用数据类型,打印arr时,会自动调用arr数组中的toString()方法,该方法默认实现的是对象类型名@该对象的hashCode()值的十六进制值。如:I@77459877
- 对象的hashCode值不一定就是对象的内存地址,此与不同品牌的JVM产品的具体实现有关。
- 数组下标从0开始的原因:第一个元素距离数组首地址间隔0个单元格
数组遍历
for(i= 0;i<one.length;i++)
注意:obj.length------代表数组的长度。利用for()循环进行遍历。注意:你要遍历几个元素你的i就小于几且i初始值定为0.
数组的常见算法
求数组最大最小值
数组元素的反转------将数组元素倒序
数组的元素查找
顺序查找
思路:查找某个元素在数组中第一次出现时的数组下标—设置一个index存储所找的元素地址下标。
二分查找(折半查找)
首先需要对数组进行从小到大排序后才可以进行二分查找
代码实现:
方式一:笨方法写
方式二:利用Arrays.binarySearch()方法------二分查找数组
注意:必须先排序才可以进行二分查找,否则Arrays.binarySearch()方法则会失效。
数组排序
各个排序算法性能分析
冒泡排序
- 原理:比较两个相邻的元素,将值大的元素交换至右端。
- 思路:一次比较相邻的两个数,将小数放到前面,大数放到后面。
- 特点:步骤重复次数:数组长度-1轮;第n轮比较次数:数组长度-n次。
- 代码实现
二维数组
- 定义:使用二维数组
- 本质:元素为一维数组的一个数组。
- 定义格式(声明数组)
动态初始化并赋值
初始化
方式一:同时初始化一维和二维数组。
初始化时同时给出一维和二维,因为二维数组是大数组上套了个小数组。
方式二:只初始化一维数组,后初始化二维数组。
先初始化一维数组,后对一维数组中的元素数组分别初始化。
赋值------详解见图所示
方式一:针对同时初始化一维和二维数组进行赋值。
方式二:针对只初始化一维数组,后初始化二维数组进行赋值
静态初始化并赋值
- 三种方式------都需要初始化并同时赋值。
- 例题演示
数组的循环遍历
一维二维数组小问题
- 同时定义一维数组和二维数组。