- 1.数组的定义
- 2.数组的动态初始化
- 3.数组元素访问
- 4.一个数组内存图
- 5.两个数组内存图
- 6.多个数组指向相同内存图
- 7.数组的静态初始化
- 8.数组操作的两个常见问题
- 9.数组的遍历
- 10.数组获取最大值
- 11.数组元素求和
- 12.数组的查找
数组(array)是一种容器,用来存储同种数据类型的多个值。
1.数组的定义第一种格式:数据类型[] 数组名
示例:
int[] arr; double[] arr; char[] arr;
第二种格式:数据类型 数组名[]
示例:
int arr[]; double arr[]; char arr[];
注意:
int[] arr; System.out.println(arr); // 此行报错
这里虽然定义了一个数组,但也仅仅只是一个数组类型的变量,变量没有进行初始化就直接使用,所以报错。
2.数组的动态初始化Java 中的数组必须先初始化,然后才能使用。
所谓初始化,就是在内存中为数组容器开辟空间,并将数据存入容器中的过程。
动态初始化:初始化时只指定数组长度,由系统为数组分配初始值。
格式:数据类型[] 数组名 = new 数据类型[数组长度];
示例:
// 通过new关键字创建了一个int类型的数组容器,该容器可以存储5个int类型的整数,该容器被arr数组变量所记录 int[] arr = new int[5];
注意:打印数组变量名,出现的是数组在内存中的地址值。
public class Demo2Array {
public static void main(String[] args) {
int[] arr = new int[5];
System.out.println(arr); // 输出:[I@10f87f48
byte[] bArr = new byte[3];
System.out.println(bArr); // 输出:[B@b4c966a
}
}
3.数组元素访问
数组内存地址的访问方式:数组名
数组内部保存的数据的访问方式:数组名[索引]
索引是数组中空间的编号
- 索引从 0 开始
- 索引是连续的
- 索引逐一增加,每次加 1
- 作用:访问数组容器中的空间位置
示例:
public class Demo3ArrayIndex {
public static void main(String[] args) {
int[] arr = new int[3]; // 索引:0 1 2
System.out.println(arr); // 数组的内存地址:[I@10f87f48
System.out.println(arr[0]); // 输出:0,即系统自动分配的默认初始化值
System.out.println(arr[1]); // 输出:0,即系统自动分配的默认初始化值
System.out.println(arr[2]); // 输出:0,即系统自动分配的默认初始化值
System.out.println("--------------");
arr[0] = 11;
arr[1] = 22;
arr[2] = 33;
System.out.println(arr[0]); // 输出:11
System.out.println(arr[1]); // 输出:22
System.out.println(arr[2]); // 输出:33
}
}
4.一个数组内存图
Java 程序在运行时,需要在内存中分配空间。为了提高运算效率,就对空间进行了不同区域的划分。每一片区域都有特定的处理数据方式和内存管理方式。
- 栈内存:方法运行时进入的内存,局部变量都存放于这块内存当中
- 堆内存:new 出来的内容都会进入堆内存,并且会存在地址值
- 方法区:字节码文件(.class文件)加载时进入的内存
- 本地方法栈:调用操作系统相关资源
- 寄存器:交给 CPU 去使用
public class Demo3 {
public static void main(String[] args) {
int[] arr = new int[3];
System.out.println(arr);
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
arr[0] = 11;
arr[1] = 22;
arr[2] = 33;
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
}
}
1.该类的字节码文件加载进方法区,main 方法存放在字节码文件中
2.main 方法被 JVM 自动调用进入栈内存执行
3.arr 数组变量在 main 方法中声明
4.new int[3]:通过 new 关健字在堆内存中开辟空间并产生地址值,因为 new 的是长度为 3 的数组所以会划分出 3 块小格子,每个格子都有自己的索引和默认初始化值
5.将地址值赋给 main 方法中的 arr 变量
5.两个数组内存图每 new 一次,在堆内存中,都是一块新的空间,堆内存中的空间地址不会出现重复的现象。
6.多个数组指向相同内存图 7.数组的静态初始化静态初始化:初始化时就可以指定数组要存储的元素,系统还会自动计算出该数组长度。
完整格式:数据类型[] 数组名 = new 数据类型[]{元素1,元素2,...};
简化格式:数据类型[] 数组名 = {元素1,元素2,...};
public class Demo1Array {
public static void main(String[] args) {
// 数据类型[] 数组名 = new 数据类型[]{数据1,数据2,数据3...};
int[] arr = new int[]{11,22,33};
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
// 数据类型[] 数组名 = {数据1,数据2,数据3...};
int[] arr2 = {44,55,66};
System.out.println(arr2);
System.out.println(arr2[0]);
System.out.println(arr2[1]);
System.out.println(arr2[2]);
}
}
动态初始化:手动指定数组长度,由系统给出默认初始化值。适用于只明确元素个数,不明确具体数值。
静态初始化:手动指定数组元素,系统会根据元素个数,计算出数组的长度。适用于需求中已经明确了要操作的具体数据。
8.数组操作的两个常见问题(1) 索引越界:访问了数组中不存在的索引对应的元素,造成索引越界问题。
public class ArrayDemo {
public static void main(String[] args) {
int[] arr = new int[3];
System.out.println(arr[3]);
}
}
数组长度为 3,索引范围是 0 ~ 2,但是我们却访问了一个 3 的索引。程序运行后,将会抛出 ArrayIndexOutOfBoundsException 数组越界异常。
(2) 空指针异常:访问的数组已经不再指向堆内存的数据,造成空指针异常。
public class ArrayDemo {
public static void main(String[] args) {
int[] arr = new int[3];
//把null赋值给数组
//null:空值,引用数据类型的默认值,表示不指向任何有效对象。
arr = null;
System.out.println(arr[0]);
}
}
arr = null 这行代码,意味着变量 arr 将不再保存数组的内存地址,也就不允许再操作数组了,因此运行的时候会抛出 NullPointerException 空指针异常。
9.数组的遍历public class ArrayTest01 {
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4, 5 };
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[3]);
System.out.println(arr[4]);
}
}
以上代码可以将数组中每个元素全部取出来,但如果数组元素非常多,这种写法肯定不行。
因此我们需要改成循环的写法,数组的索引是 0 到 length - 1,可以作为循环的条件。
public class ArrayTest01 {
public static void main(String[] args) {
//定义数组
int[] arr = {11, 22, 33, 44, 55};
//使用通用的遍历格式
for(int x = 0; x < arr.length; x++) {
System.out.println(arr[x]);
}
}
}
10.数组获取最大值
思路如下:
public class Test2Array {
public static void main(String[] args) {
int[] arr = {12,45,98,73,60};
// 1.定义一个变量 max 用于保存最大值,首先假设数组中的第一个元素最大
int max = arr[0];
// 2.遍历数组,如果出现了比 max 更大的,就让 max 记录更大的值
for(int i = 1; i < arr.length; i++){
if(arr[i] > max){
max = arr[i];
}
}
// 3.循环结束后,变量 max 保存的就是整个数组的最大值
System.out.println("max:" + max);
}
}
11.数组元素求和
示例:键盘录入 5 个整数,存储到数组中,并对数组求和。
import java.util.Scanner;
public class Test3Array {
public static void main(String[] args) {
// 1.创建键盘录入对象,准备键盘录入
Scanner sc = new Scanner(System.in);
// 2.定义一个求和变量,准备记录累加后的结果
int sum = 0;
// 3.动态初始化一个长度为5的int数组,准备存储键盘录入的数值
int[] arr = new int[5];
// 4.将键盘录入的数值存储到数组中
for(int i = 0; i < arr.length; i++){
System.out.println("请输入第" + (i+1) + "个整数:");
arr[i] = sc.nextInt();
}
// 5.遍历数组,取出每一个元素,并求和
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
// 6.输出总和
System.out.println("sum:" + sum);
}
}
12.数组的查找
示例:已知一个数组 arr = {19, 28, 37, 46, 50},键盘录入一个数据,查找该数据在数组中的索引,并在控制台输出找到的索引值。
public static void main(String[] args) {
// 1.定义一个数组,用静态初始化完成数组元素的初始化
int[] arr = {19, 28, 37, 46, 50};
// 2.键盘录入要查找的数据,用一个变量接收
Scanner sc = new Scanner(System.in);
System.out.println("请输入您要查找的元素:");
int num = sc.nextInt();
// 3.定义一个索引变量,初始值为-1,假设要查找的数据在数组中是不存在的
int index = -1;
// 4.遍历数组,获取到数组中的每一个元素
for (int i = 0; i < arr.length; i++) {
// 5.拿键盘录入的数据和数组中的每一个元素进行比较
if(num == arr[i]){
// 如果值相同,就把该值对应的索引赋值给索引变量,并结束循环
index = i;
break;
}
}
// 6.输出索引变量
System.out.println(index);
}
}



