一、数组类型定义
* 在java中使用数组必须先进行类型说明。
数组说明的一般形式为:类型说明符 数组名 [常量表达式],……;
其中,类型说明符是任一种基本数据类型或构造数据类型。数组名是用户定义的数组标识符。方括号中的常量表达式表示数据元素的个数,也称为数组的长度。
数组就是一次性定义相同数据类型的一组变量数组定义。
*举例
int a[10]; 说明整型数组a,有10个元素。若要表示第10个元素,则使用a[9]。第一个则是a[0]。
float b[10],c[20]; 说明实型数组b,有10个元素,实型数组c,有20个元素。
char ch[20]; 说明字符数组ch,有20个元素。
*特点
1.数组是相同数据类型的元素的集合。
2.数组中的各元素的存储是有先后顺序的,它们在内存中按照这个先后顺序连续存放在一起。
3.数组元素用整个数组的名字和它自己在数组中的顺序位置来表示。例如,a[0]表示名字为a的数组中的第一个元素,a[1]代表数组a的第二个元素,以此类推。
*一维数组
①定义:一维数组是最简单的数组,其逻辑结构是线性表。要使用一维数组,需经过定义、初始化和应用等过程。
②数组声明: 在数组的声明格式里,“数据类型”是声明数组元素的数据类型,可以是java语言中任意的数据类型,包括简单类型和结构类型。
“数组名”是用来统一这些相同数据类型的名称,其命名规则和变量的命名规则相同。
数组声明之后,接下来便是要分配数组所需要的内存,这时必须用运算符new,其中“个数”是告诉编译器,所声明的数组要存放多少个元素,所以new运算符是通知编译器根据括号里的个数,在内存中分配一块空间供该数组使用。利用new运算符为数组元素分配内存空间的方式称为动态分配方式。
③举例:
int[] x; //声明名称为x的int型数组
x=new int[10]; //x数组中包含有10个元素,并为这10个元素分配内存空间
在声明数组时,也可以将两个语句合并成一行,利用这种格式在声明数组的同时,也分配一块内存供数组使用,格式如下:
数据类型[] 数组名= new 数据类型[个数];
int[] x = new int [10];
int[] x= new int{1,3,9,4};
等号左边的int[]x相当于定义了一个特殊的变量x,x的数据类型是一个对int型数组对象的引用,x就是一个数组的引用变量,其引用的数组元素个数不定。等号右边的new int[10]就是在堆内存中创建一个具有10个int型变量的数组对象。int[]x = new int [10];就是将右边的数组对象赋值给左边的数组引用变量。[5]
*二维数组
①定义:前面介绍的数组只有一个下标,称为一维数组, 其数组元素也称为单下标变量。在实际问题中有很多量是二维的或多维的, 因此Java中允许构造多维数组。多维数组元素有多个下标, 以标识它在数组中的位置,所以也称为多下标变量。
②二维数组类型说明的一般形式是:
类型说明符数组名[常量表达式1][常量表达式2]…;
其中常量表达式1表示第一维下标的长度,常量表达式2 表示第二维下标的长度
int[][] arr2=new int[3][4];
♦ int[][] arr=new int[4][]; //首先开辟一个4行的一维数组
arr[0]=new int[]{12}; //然后给每一行数组进行赋值
arr[1]=new int[]{8,9}; //此时相当于新new了一个一维数组,然后将一维数组的地址,赋给arr[i]
arr[2]=new int[]{11,7,16}; //所以,在二维数组中,一维一般存的都是地址
arr[3]=new int[]{13,9,8,7};
注意:在二维数组中,一维一般存储地址
♥arr arr1打印出是地址,是因为数组为引用数据类型,变量里存储地址,且变量在栈里存放,而new出来的数组内容在堆里存放
♥arr[0]打印出来是地址是因为在二维数组中,一维存放地址,二维存放内容,因此arr[0][1]打印出来是数值。
二维数组在概念上是二维的,即是说其下标在两个方向上变化, 下标变量在数组中的位置也处于一个平面之中, 而不是象一维数组只是一个向量。但是,实际的硬件存储器却是连续编址的, 也就是说存储器单元是按一维线性排列的。如何在一维存储器中存放二维数组,可有两种方式:一种是按行排列, 即放完一行之后顺次放入第二行。另一种是按列排列, 即放完一列之后再顺次放入第二列。在C语言中,二维数组是按行排列的。在如上中,按行顺次存放,先存放a[0]行,再存放a[1]行,最后存放a[2]行。每行中有四个元素也是依次存放。由于数组a说明为int类型,该类型占两个字节的内存空间,所以每个元素均占有两个字节(图中每一格为一字节)。
*三维数组
三维数组,是指维数为三的数组结构。三维数组是最常见的多维数组,由于其可以用来描述三维空间中的位置或状态而被广泛使用。
三维数组就是维度为三的数组,可以认为它表示对该数组存储的内容使用了三个独立参量去描述,但更多的是认为该数组的下标是由三个不同的参量组成的。
数组这一概念主要用在编写程序当中,和数学中的向量、矩阵等概念有一定的差别,主要表现:在数组内的元素可以是任意的相同数据类型,包括向量和矩阵。
对数组的访问一般是通过下标进行的。在三维数组中,数组的下标是由三个数字构成的,通过这三个数字组成的下标对数组的内容进行访问。
二、数组的内存分配
*栈内存
在方法中定义的一些基本类型的变量和对象的引用变量都在方法的栈内存中分配,当在一段代码中定义一个变量时,java就在栈内存中为这个变量分配内存空间,当超出变量的作用域后,java会自动释放掉为该 变量所分配的内存空间。
*堆内存
堆内存用来存放由new运算符创建的对象和数组,在堆中分配的内存,由java虚拟机的自动垃圾回收器来管理。在堆中创建了一个数组或对象后,同时还在栈内存中定义一个特殊的变量。让栈内存中的这个变量 的取值等于数组或者对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量,引用变量实际上保存的是数组或对象在堆内存中的地址(也称为对象的句柄),以后就可以在程序中使用栈的引用变 量来访问堆中的数组或对象
三、数组的特征
* 1.定义数组必须指定大小
* 2.数组的每一个元素的内存都是连续的
* 3.数组的随机访问操作,是一个常量时间 arr[index]
* 4.每一个数组都内置了一个成员变量 length,表示数组的总长度
* 5.数组增加元素,涉及增加位置后面的所有元素都要进行移动,所以该操作花费的
* 时间线性时间
* 6.数组删除元素,涉及增加位置后面的所有元素都要进行移动,所以该操作花费的
* 时间线性时间
* 7.数组的元素查找花费时间为线性时间
四、数组的三种输出方式
①方式一:
// 输出数组方式一 标准for循环
for (int i = 0; i < arr.length; i++)
{
System.out.print(arr[i] + " ");
}
②方式二
// 输出数组方式二 foreach arr.length
for (int val : arr)
{
System.out.print(val + " "); //用于输出一维数组
}
/*****************************/
for(int[] ints:arr)
{
for(int val: ints)
{
System.out.print(val+" "); //用于输出二维数组
}
}
③方式三
//输出数组方式三 Arrays.toString输出数组元素的内容
System.out.println(Arrays.toString(arr)); //用于输出一维数组
System.out.println(Arrays.deepToString(arr)); //用于输出二维数组
五,数组的辅助类Arrays
Arrays.copyOf 数组的扩容和缩容
Arrays.toString 打印数组元素
Arrays.deepToString 打印二维数组元素的值
Arrays.fill 给数组初始化/重置
Arrays.equals 比较两个数组的内容是否相等
练习题:(分苹果问题)
n个奶牛,每个奶牛拥有的苹果数量不相同,现要求你每次只能从一个奶牛身上取两个苹果起给其他奶牛,问要至少移动多少次,可以将苹果均分,如果方案不存在输出-1。
练习题:(最长路径问题)
* 12
8 9
11 7 16
13 9 8 7
可以从每个结点 往下,往左斜下,往右斜下分别遍历,以致找到一条从上到下的最长路径。
练习题:定义一个容量为100的数组,给每个元素随机分配一个数,范围在【101,200】,先打印出其中的偶数,然后将其容量扩大到200,使其前面的数值大小不发生改变,并给后100个元素也随机分配【0,50】的任意一个数。