一.数组概念
(一)数组的概念:
数组就是存储数据长度固定的容器,保证多个数据的数据类型要一致
(二)数组的特点:
- 数组是一种引用数据类型
- 数组当中的多个数据,类型必须统一
- 数组的长度在程序运行期间不可改变
二.数组的定义
在内存当中创建一一个数组, 并且向其中赋予一些默认值。
(一)两种常见的初始化方式:
1.动态初始化(指定长度)
(1)格式:数据类型[] 数组名称 = new 数据类型[数组长度];
例:int[] arrayA = new int[3];
(2)数组定义格式详解:
- 左侧数据类型:创建的数组容器可以存储什么数据类型。
- 左侧[]:表示数组。
- 左侧数组名称 :为定义的数组起个变量名,满足标识符规范,可以使用名称操作数组。
- 右侧new:关键字,创建数组使用的关键字。
- 右侧数据类型:创建的数组容器可以存储什么数据类型,必须与左边相一致
- 右侧[数组长度]:数组的长度,表示数组容器中可以存储多少个元素。
注意:数组有定长特性,长度一旦指定,不可更改。
2.静态初始化(指定内容)
(1)标准格式:
数据类型[] 数组名称 = new 数据类型[] {元素1,元素2,... };
例:int[] arrayB = new int[]{1, 2, 3};
(2)省略格式:
数据类型[] 数组名称 = {元素1,元素2,... };
例:int[] arrayC = {1, 2, 3};
(二)注意事项:
- 静态初始化没有直接指定长度,但是仍然会自动推算得到长度。
- 静态初始化标准格式可以拆分成为两个步骤。
- 动态初始化也可以拆分成为两个步骤。
- 静态初始化一旦使用省略格式, 就不能拆分成为两个步骤了。|
代码:
public class Array {
public static void main(String[] args) {
int[] arrayA = new int[3];
// 拆分成两个步骤
int[] arrayA1;
arrayA1 = new int[3];
int[] arrayB = new int[]{1, 2, 3};
//拆分成两个步骤
int[] arrayB1;
arrayB1 = new int[]{1, 2, 3};
int[] arrayC = {1, 2, 3};
}
}
三.数组的访问
(一)索引:
每一个存储到数组的元素,都会自动的拥有一个编号,从0开始,这个自动编号称为数组索引(index),可以通过数组的索引访问到数组中的元素。
(二)访问数组元素:
1.格式
数组名称[索引值]
2.索引值
就是一个int数字, 代表数组当中元素的编号。
索引值从0开始,一直到数组的长度-1为止。
3.索引访问数组中的元素
(1)变量=数组名[索引]
,获取出数组中的元素
代码:
public class Array {
public static void main(String[] args) {
// 静态初始化的标准格式
String[] array = new String[]{"Hello", "World", "!"};
System.out.println(array);
// 直接打印数组当中的元素
System.out.print(array[0]); // Hello
System.out.print(array[1]); // World
System.out.println(array[2]); // !
// 也可以将数组当中的某一个单个元素,赋值交给变量
String str = array[1];
System.out.println("数组当中第1号元素是:"+str); // World
}
}
运行结果:
使用动态初始化数组的时候,其中的元素将会自动拥有一一个默认值。规则如下:
数据类型 默认值
基本类型 整数(byte,short,int,long) 0
浮点数(float,double) 0.0
字符(char) '\u0000'
布尔(boolean) false
引用类型 数组,类,接口 null
注意事项:
静态初始化其实也有默认值的过程,只不过系统自动马上将默认值替换成为了大括号当中的具体数值。
代码:
public class Array {
public static void main(String[] args) {
// 静态初始化的标准格式
String[] array = new String[3];
System.out.println(array); // 内存地址值
System.out.println(array[0]); // null
System.out.println(array[1]); // null
System.out.println(array[2]); // null
}
}
运行结果:
(2)数组名[索引]=数值
,为数组中的元素赋值
代码:
public class Array {
public static void main(String[] args) {
// 静态初始化的标准格式
String[] array = new String[3];
System.out.println(array); // 内存地址值
System.out.println(array[0]); // null
System.out.println(array[1]); // null
System.out.println(array[2]); // null
System.out.println("===================");
// 将数据World赋值交给数组array
array[1] = "World";
System.out.println(array[0]); // null
System.out.println(array[1]); // World
System.out.println(array[2]); // null
}
}
运行结果:
四.数组的内存图
(一)一个数组的内存图
代码:
public class ArrayOne {
public static void main(String[] args) {
int[] array = new int[3]; // 动态初始化
System.out.println(array); // 地址值
System.out.println(array[0]); // 0
System.out.println(array[1]); // 0
System.out.println(array[2]); // 0
// 改变数组当中元素的内容
array[1] = 10;
array[2] = 20;
System.out.println(array); // 地址值
System.out.println(array[0]); // 0
System.out.println(array[1]); // 10
System.out.println(array[2]); // 20
}
}
运行结果:
内存图
(二)两个独立数组的内存图
代码:
public class ArrayTwo {
public static void main(String[] args) {
int[] arrayA = new int[3]; // 动态初始化
System.out.println(arrayA); // 地址值
System.out.println(arrayA[0]); // 0
System.out.println(arrayA[1]); // 0
System.out.println(arrayA[2]); // 0
System.out.println("===============");
// 改变数组当中元素的内容
arrayA[1] = 10;
arrayA[2] = 20;
System.out.println(arrayA); // 地址值
System.out.println(arrayA[0]); // 0
System.out.println(arrayA[1]); // 10
System.out.println(arrayA[2]); // 20
System.out.println("===============");
int[] arrayB = new int[3]; // 动态初始化
System.out.println(arrayB); // 地址值
System.out.println(arrayB[0]); // 0
System.out.println(arrayB[1]); // 0
System.out.println(arrayB[2]); // 0
System.out.println("===============");
// 改变数组当中元素的内容
arrayB[1] = 100;
arrayB[2] = 200;
System.out.println(arrayB); // 地址值
System.out.println(arrayB[0]); // 0
System.out.println(arrayB[1]); // 100
System.out.println(arrayB[2]); // 200
}
}
运行结果:
内存图
(三)两个引用指向同一个数组的内存图
代码:
public class ArraySame {
public static void main(String[] args) {
int[] arrayA = new int[3]; // 动态初始化
System.out.println(arrayA); // 地址值
System.out.println(arrayA[0]); // 0
System.out.println(arrayA[1]); // 0
System.out.println(arrayA[2]); // 0
System.out.println("===============");
// 改变数组当中元素的内容
arrayA[1] = 10;
arrayA[2] = 20;
System.out.println(arrayA); // 地址值
System.out.println(arrayA[0]); // 0
System.out.println(arrayA[1]); // 10
System.out.println(arrayA[2]); // 20
System.out.println("===============");
int[] arrayB = arrayA; // 动态初始化
System.out.println(arrayB); // 地址值
System.out.println(arrayB[0]); // 0
System.out.println(arrayB[1]); // 10
System.out.println(arrayB[2]); // 20
System.out.println("===============");
// 改变数组当中元素的内容
arrayB[1] = 100;
arrayB[2] = 200;
System.out.println(arrayB); // 地址值
System.out.println(arrayA[0]); // 0
System.out.println(arrayB[0]); // 0
System.out.println(arrayA[1]); // 100
System.out.println(arrayB[1]); // 100
System.out.println(arrayA[2]); // 200
System.out.println(arrayB[2]); // 200
}
}
运行结果:
内存图
五.数组的常见异常
(一)数组索引越界异常
数组的索引编号从0开始,一直到“数组的长度- 1”为止。如果访问数组元素的时候,索引编号并不存在,那么将会发生数组索引越界异常ArrayIndexOutOfBoundsException
代码:
public class ArrayIndex {
public static void main(String[] args) {
int[] array = {15, 25, 35};
System.out.println(array[0]); // 15
System.out.println(array[1]); // 25
System.out.println(array[2]); // 35
//错误写法
//并不存在三号元素,所以发生异常
System.out.println(array[3]);
}
}
运行结果:
(二)空指针异常
所有的引用类型变量,都可以赋值为一个null值。但是代表其中什么都没有。数组必须进行new初始化才能使用其中的元素。如果只是赋值了一个null,没有进行new创建,那么将会发生:空指针异常NullPointerException
代码:
public class ArrayNull {
public static void main(String[] args) {
int[] array= null;
System.out.println(array[0]);
}
}
运行结果:
五.数组的遍历
(一).数组的长度
数组的长度属性: 每个数组都具有长度,而且是固定的,Java中赋予了数组的一个属性,可以获取到数组的长度,
语句为:数组名.length
,属性length的执行结果是数组的长度,int类型结果。由次可以推断出,数组的最大索引值为数组名.length-1
。
代码:
public class Array {
public static void main(String[] args) {
int[] arr = new int[]{1, 2, 3, 4, 5};
//打印数组的属性,输出结果是5
System.out.println("数组的长度是:" + arr.length);
}
}
运行结果:
注意事项:数组一旦创建,程序运行期间,长度不可改变。
代码:
public class ArrayLength {
public static void main(String[] args) {
int[] arrayC = new int[3];
System.out.println(arrayC);
System.out.println(arrayC.length);
System.out.println("=================");
arrayC = new int[5];
System.out.println(arrayC);
System.out.println(arrayC.length);
}
}
运行结果:
解释:数组是在堆中存放,长度不能发生改变。重新new是新建了一个数组,并用arrayC指向了新的数组。
(二).遍历数组
数组遍历: 就是将数组中的每个元素分别获取出来。遍历也是数组操作中的基石。
代码:
public class Array {
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6};
// 正序遍历数组
for (int i = 0; i < array.length; i++) {
System.out.print(array[i]);
}
System.out.println();
// 正序遍历数组省略格式
for (int value : array) {
System.out.print(value);
}
System.out.println();
// 倒序遍历数组
for (int i = array.length - 1; i >= 0; i--) {
System.out.print(array[i]);
}
}
}
运行结果:
六.数组作为方法参数和返回值
(一)数组作为方法参数
数组可以作为方法的参数。当调用方法的时候,向方法的小括号进行传参,传递进去的其实是数组的地址值。
- 数组作为方法参数传递,传递的参数是数组的内存地址。
代码:
public class ArrayParam {
public static void main(String[] args) {
int[] array = {10, 20, 30, 40, 50};
System.out.println(array);
printArray(array);
System.out.println("======AAA======");
printArray(array);
System.out.println("======BBB======");
printArray(array);
}
public static void printArray(int[] array) {
System.out.println("printArray方法收到的参数是:" + array);
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
运行结果:
(二) 数组作为方法返回值
数组可以作为方法的返回值。当调用方法的时候,使用return语句返回数组,返回的其实是数组的地址值。
- 数组作为方法的返回值,返回的是数组的内存地址
代码
public class ArrayReturn {
public static void main(String[] args) {
int[] result = calculate(10, 20, 30);
System.out.println("main方法接收到的返回值数组是:" + result); // 地址值
System.out.println("总和:" + result[0]);
System.out.println("平均数" + result[1]);
}
public static int[] calculate(int a, int b, int c) {
int sum = a + b + c;
int avg = sum / 3;
int[] array = {sum, avg};
System.out.println("calculcate方法内部数组是:" + array); // 地址值
return array;
}
}
运行结果:
注意事项:
- 任何数据类型都能作为方法的参数类型,或者返回值类型。
- 数组作为方法的参数,传递进去的其实是数组的地址值。
- 数组作为方法的返回值,返回的其实也是数组的地址值.