基础概念
数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理。
概述
- 数据本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。
- 创建数组对象会在内存中开辟一整块连续的空间,而数组名中引用的是这块连续空间的首地址。
- 数组的长度一旦确定,就不能修改。
- 我们可以直接通过下标(或索引)的方式调用指定位置的元素,速度很快。
- 数组的分类:
- 按照维度可以分为:一维数组,二维数组,三维数组,…
- 按照元素的数据类型可以分为:基本数据类型元素的数组,引用数据类型元素的数组
一维数组的使用
语法
type var[]
或
type[] var
例如:
int a[];
int[] al;
double b[];
String[] c; // 引用类型变量数组
注意:在声明数组时不能指定其长度,例如: int a[5];
数组的初始化
-
动态初始化
数组声明且为数组元素分配空间与赋值的操作分开进行。
class ArrayTest { public static void main(String[] args) { int[] arr = new int[3]; arr[0] = 3; arr[1] = 9; arr[2] = 8; String names[]; names = new String[3]; names[0] = "钱学森"; names[1] = "邓稼先"; names[2] = "袁隆平"; } }
-
静态初始化
在定义数组的同时就为数组元素分配空间并赋值。
class ArrayTest { public static void main(String[] args) { int arr1[] = new int[]{3,4,5,6}; int[] arr2 = {3,4,5,6}; String names[] = { "李四光","茅以升","华罗庚" }; } }
数组元素的引用
-
定义并用运算符new为之分配空间后,才可以引用数组中的每个元素;
-
数组元素的引用方式:数组名[数组元素下标]
-
数组元素下标可以是整型常量或者整型表达式。如a[3],b[i],c[6*i];
-
数组元素下标从0开始;长度为n的数组合法下标取值范围:0–>n-1;例如 int a[] = new int[3]可引用的数组元素有a[0]、a[1]、a[2]
-
class ArrayTest { public static void main(String[] args) { int[] arr = new int[3]; arr[0] = 3; arr[1] = 4; arr[2] = 5; System.out.println(arr[0]); // 3 System.out.println(arr[1]); // 4 System.out.println(arr[2]); // 5 } }
-
-
每个数组都有一个属性length指明它的长度,例如:a.length指明数组a的长度(元素个数)
-
class ArrayTest { public static void main(String[] args) { int[] arr = new int[3]; arr[0] = 3; arr[1] = 4; arr[2] = 5; System.out.println(arr.length); // 3 } }
-
数组一旦初始化,长度不可变
-
-
数组是引用数据类型,他的元素相当于类的成员变量,因此数组一经分配空间,其中的每个元素也被按照成员变量同样的方式被隐式初始化。
-
class ArrayTest { public static void main(String[] args) { int[] arr = new int[3]; System.out.println(arr[0]); // 0 System.out.println(arr[1]); // 0 System.out.println(arr[2]); // 0 } }
-
对于基本数据类型而言,默认初始化值各有不同
-
对于引用数据类型而言,默认初始化值为null
-
数组元素类型 元素默认初始值 byte 0 short 0 int 0 long 0L float 0.0F double 0.0 char \u0000 boolean false 引用类型 null
-
内存解析
int[] arr = new int[3]{1,2,3};
// 在栈中添加一个变量arr,在堆中开辟一块区域,长度为3
// 最开始堆中保存的数据是默认值0,然后对他们进行修改,修改为1,2,3
System.out.println(arr);
// 栈的区域内部保存着一个指针,内容是 [I@15db9742
// 他指向堆中保存数据的区域的首地址
String[] arr1 = new String[4];
// 在栈中添加一个变量arr1,因为比arr后创建,所以在arr上.(越先入栈,在栈中位置越靠下)
// 在堆中开辟一块区域,长度为4,因为此时没有赋值,所以内部都是null(null是空的意思,不等于0)
arr1[1] = "刘德华";
// 对索引为1的块赋值,替换原有的null
arr1[2] = "张学友";
// 同理
System.out.println(arr1);
// 此时变量arr1的指针是 [Ljava.lang.String;@6d06d69c
arr1 = new String[3];
// 本来我们是有arr1变量的,但是现在使用new重新创建了arr1变量。
// 在堆中重新开辟一块区域,这个区域与原来的区域没有关系。
System.out.println(arr1);
// 这个arr1变量和原来的arr1变量没有关系。
注意:堆中存储数据的区域是随机分布的,这样画只是简洁一些。
练习
class ArrayTest {
public static void main(String[] args) {
int[] arr = new int[]{8,2,1,0,3};
int[] index = new int[]{2,0,3,2,4,0,1,3,2,3,3};
String tel = "";
for(int i = 0;i < index.length;i ++){
tel += arr[index[i]];
}
System.out.print(tel);
}
}
多维数组
- Java语言里提供了支持多维数组的语法。
- 如果说可以把一维数组当成表格中的一行,那么二维数组就相当于是一个表格。
- 可以将一维数组作为另一个一维数组的元素而存在,这就是一个二维数组。
- 从数组底层的运行机制来看,其实没有多维数组。
语法
type var[][]
或
type[][] var
例如
int a[][];
int[][] al;
double b[][];
String[][] c;
数组的初始化
-
动态初始化
动态初始化有两种形式。
-
int[][] arr = new int[3][2];
-
定义了名称为arr的二维数组
-
二维数组中有3个一维数组
-
每一个一维数组中有2个元素
-
一维数组的名称分别为arr[0],arr[1],arr[2]
-
给第一个一维数组赋值的写法
arr[0][0] = 1; arr[0][1] = 2;
-
-
int[][] arr = new int[3][];
-
二维数组中有3个一维数组。
-
每个一维数组都默认初始化值为null
-
可以对这三个一维数组分别进行初始化
arr[0] = new int[3]; arr[1] = new int[1]; arr[2] = new int[2];
-
-
-
静态初始化
-
int[][] arr = new int[][]{{3,8,2},{2,7},{9,0,1,6}};
-
定义一个名称为arr的二维数组,二维数组中有三个一维数组
-
每一个一维数组中具体元素也都已初始化
-
第一个一维数组 arr[0] = {3,8,2}
-
第二个一维数组 arr[1] = {2,7}
-
第三个一维数组 arr[2] = {9,0,1,6}
-
使用length表示方式:arr[0].length
-
-
注意:特殊写法:int[] x,y[];x是一维数组,y是二维数组。且多维数组不必是矩形
内存解析
int[][] arr = new int[4][];
arr[0] = new int[3];
arr[1] = new int[]{1,2,3};
arr[0][2] = 5;
arr = new int[2][2];
练习
class ArraysTest{
public static void main(String[] args) {
/**
* 练习1
* 有表格如下
* 3 5 8 -
* 12 9 - -
* 7 0 6 4
*
* 求和
*/
int[][] arr = new int[3][];
arr[0] = new int[3];
arr[0][0] = 3;
arr[0][1] = 5;
arr[0][2] = 8;
arr[1] = new int[2];
arr[1][0] = 12;
arr[1][1] = 9;
arr[2] = new int[4];
arr[2][0] = 7;
arr[2][1] = 0;
arr[2][2] = 6;
arr[2][3] = 4;
int sum = 0;
for(int i = 0;i < arr.length;i ++){
for(int j = 0;j < arr[i].length;j ++){
sum += arr[i][j];
}
}
System.out.println(sum);
/**
* 练习2
* 打印一个10行的杨辉三角形
*/
int[][] yanghui = new int[10][];
for(int i = 0;i < yanghui.length;i ++){
yanghui[i] = new int[i+1];
for(int j = 0;j < yanghui[i].length;j ++){
if(j == 0 || j == yanghui[i].length-1 ){
yanghui[i][j] = 1;
}else{
yanghui[i][j] = yanghui[i-1][j-1] + yanghui[i-1][j];
}
}
}
for(int i = 0;i < yanghui.length;i ++){
for(int j = 0;j < yanghui[i].length;j ++){
System.out.print(yanghui[i][j] + " ");
}
System.out.println();
}
/**
* 练习3
* 创建一个长度为6的int型数组,要求数组元素的值在1-30之间。
* 随机赋值,而且所有的值各不相同。
*/
int[] arr1 = new int[6];
for (int i = 0;i < arr1.length;i ++) {
while(true) {
int num =(int) (Math.random()*30 + 1);
int count = 0;
for (int j = 0;j < arr1.length;j ++) {
if (arr1[j] == num) {
count++;
}
}
if (count == 0) {
arr1[i] = num;
break;
}
}
}
for (int k : arr1) {
System.out.print(k + " ");
}
}
}