Java基础03——数组
一、数组介绍
什么是数组:
- 数组指的是一种容器,可以用来存储同种数据类型的多个值。
- 数组容器在存储数据的时候,需要结合隐式转换考虑。
-
- int类型的数组容器(
boolean、byte、short、int、double)
- int类型的数组容器(
-
- double类型的数组容器(byte、short、int、long、float、double)
二、数组的定义与静态初始化
1. 定义数组
- 格式一(常用):数据类型[] 数组名
-
int[] array
- 格式二:数据类型 数组名[]
-
int array[]
2. 数组静态初始化
初始化:就是在内存中,为数组容器开辟空间,并将数据存入容器中的过程。
定义数组是给数组名字,初始化数组是给数组开辟内存空间。
- 格式:数据类型[] 数组名 = new 数据类型[]{元素1, 元素2…};
- 简化格式:数据类型[] 数组名 = {元素1, 元素2…};
- 数组静态初始化后,数组长度不能改变。
- 示例:
public class Main { public static void main(String[] args) { // 定义数组,存储5个学生的年龄 int[] age1 = new int[]{11, 12, 13, 14, 15}; int[] age2 = {11, 12, 13, 14, 15}; // 定义数组,存储3个学生的姓名 String[] name1 = new String[]{"张三", "李四", "王五"}; String[] name2 = {"张三", "李四", "王五"}; // 定义数组,存储4个学生的身高 double[] height1 = new double[]{1.93, 1.75, 1.73, 1.81}; double[] height2 = {1.93, 1.75, 1.73, 1.81}; } }
三、数组元素访问
1. 数组的地址值
- 如果直接输出数组,会显示数组的地址值。
- 平时习惯性的把整体叫做数组的地址值。
public class Main {
public static void main(String[] args) {
int[] age1 = new int[]{11, 12, 13, 14, 15};
double[] height1 = new double[]{1.93, 1.75, 1.73, 1.81};
System.out.println(age1); // [I@2c8d66b2
System.out.println(height1); // [D@5a39699c
}
}
[I@2c8d66b2
[ : 表示当前是一个数组
I : 表示当前数组里面的元素都是int类型
@:表示一个间隔符号(固定格式)
2c8d66b2:数组真正的地址值(十六进制)
2. 数组访问
- 格式:数组名[索引]
public class Main {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4};
// 返回0索引上对应的元素
System.out.println(arr[0]); // 1
// 把数据存储到数组中
// 数据覆盖后,原来的数据就不存在了。、
arr[0] = 100;
System.out.println(arr[0]); // 100
}
}
四、数组遍历
- 数组遍历:指的是取出数据的过程。将数组中所有的内容取出来,取出来后可以(打印、求和、判断…)
- 遍历示例:
public class Main { public static void main(String[] args) { int[] arr = {1, 2, 3}; for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } } }
五、数组动态初始化
- 初始化时只指定数组长度,由系统为数组分配初始值。
- 格式:数据类型[] 数组名 = new 数据类型[数组长度];
- 示例:
public class Main { public static void main(String[] args) { // 定义一个数组,存储班级里50个学生的姓名,姓名未知 String[] name = new String[50]; name[0] = "张三"; name[1] = "李四"; System.out.println(name[0]); // 张三 System.out.println(name[1]); // 李四 System.out.println(name[2]); // 打印出来的是默认初始化值null } }
- 数组默认初始化值的规律:
数据类型 | 默认初始化值 |
---|---|
整型 | 0 |
小数类型 | 0.0 |
字符类型 | \u0000 (空格) |
布尔类型 | false |
引用数据类型 | null |
- 静态初始化和动态初始化的区别
-
- 静态初始化:手动指定数组元素,系统会根据元素个数,计算出数组的长度。
-
-
- 需求中已经明确了要操作的具体数据,直接静态初始化即可。
-
-
- 动态初始化:手动指定数组长度,由系统给出默认初始化值。
-
-
- 只明确元素个数,不明确具体数值,推荐使用动态初始化。
-
六、数组常见问题
1. 索引越界异常
- 原因:访问了不存在的索引
- 异常类型:ArrayIndexOutOfBoundsException
- 异常显示:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 55 out of bounds for length 50
at day05.Main.main(Main.java:11)
七、数组常见操作
1. 求最值
public class Main {
public static void main(String[] args) {
int[] arr = {33, 5, 22, 44, 55};
// 临时认为0索引的数据是最大的
int max = arr[0];
// 拿每一个元素跟max进行比较
// 循环开始条件可以写1
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
System.out.println(max); // 55
}
}
2. 求和
import java.util.Random;
public class Main {
public static void main(String[] args) {
Random random = new Random();
// 定义数组
int[] arr = new int[10];
// 随机生成10个数存入数组
for (int i = 0; i < arr.length; i++) {
int number = random.nextInt(100) + 1;
arr[i] = number;
}
// 数组求和
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
System.out.println("数组中所有数据的和为:" + sum);
System.out.println("数组中平均数为:" + (sum / arr.length));
}
}
3. 交换数据
public class Main {
public static void main(String[] args) {
// 定义数组
int[] arr = {1, 2, 3, 4, 5};
// 遍历交换数据
for (int i = 0, j = arr.length - 1; i < j; i++, j--) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " "); // 5 4 3 2 1
}
}
}
4. 打乱数据
import java.util.Random;
public class Main {
public static void main(String[] args) {
Random random = new Random();
// 定义数组
int[] arr = {1, 2, 3, 4, 5};
for (int i = 0; i < arr.length; i++) {
// 生成随机索引
int randomIndex = random.nextInt(arr.length);
int temp = arr[i];
arr[i] = arr[randomIndex];
arr[randomIndex] = temp;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
}
八、数组内存图
- java中内存分配
JVM内存空间 | 作用 |
---|---|
栈 | 方法运行时使用的内存,比如main方法运行,进入方法栈中执行 |
堆 | 存储对象或数组,new来创建的都存储在堆内存 |
方法区 | 存储可以运行的class文件 |
本地方法栈 | JVM在使用操作系统功能的时候使用,与开发无关 |
寄存器 | 给CPU使用,与开发无关 |
- 栈内存:程序的主入口(main方法),开始执行时会进栈,代码执行完毕会出栈。
- 堆内存:new出来的东西会在堆内存中开辟空间并产生地址。如果new了多次,会在堆内存中开辟多个地址空间。
- 两个数组指向同一个内存空间时,其中一个数组的值发生改变,其他数组的值也会发生改变。
public class Main { public static void main(String[] args) { int[] arr1 = {11, 22}; int[] arr2 = arr1; System.out.println(arr1[0]); // 11 System.out.println(arr2[0]); // 11 arr2[0] = 33; System.out.println(arr1[0]); // 33 System.out.println(arr2[0]); // 33 } }
九、二维数组
1. 初始化二维数组
- 静态初始化:
-
- 一般格式:数据类型[][] 数组名 = new 数据类型[][] {{元素1, 元素2}, {元素1, 元素2}}
-
- 简化格式:数据类型[][] 数组名 = {{元素1, 元素2}, {元素1, 元素2}}
- 动态初始化:
-
- 一般格式:数据类型[][] 数组名 = new 数据类型[m][n]
public class Main {
public static void main(String[] args) {
// 静态初始化定义一个二维数组
int[][] arr1 = {
{1, 2, 3},
{4, 5, 6, 7, 8, 9}
};
// 动态初始化定义一个二维数组
int[][] arr2 = new int[3][5];
}
}
2. 遍历二维数组
public class Main {
public static void main(String[] args) {
// 动态初始化定义一个二维数组
int[][] arr2 = new int[3][5];
// 遍历二维数组
for (int i = 0; i < arr1.length; i++) {
for (int k = 0; k < arr1[i].length; k++) {
System.out.print(arr1[i][k] + " ");
}
System.out.println();
}
}
}
3. 不等长二维数组
public class Main {
public static void main(String[] args) {
int[][] arr = new int[2][];
int[] arr1 = {11, 22};
int[] arr2 = {44, 55, 66};
arr[0] = arr1;
arr[1] = arr2;
}
}
4. 二维数组地址覆盖
public class Main {
public static void main(String[] args) {
int[][] arr = new int[2][3];
int[] arr1 = {11, 22};
int[] arr2 = {44, 55, 66};
// 新的数组地址覆盖旧地址
arr[0] = arr1;
arr[1] = arr2;
}
}