JavaSE初学(3)
第三章 数组
数组是 Java 中最基础、最常用的数据结构之一,用于存储固定大小的同类型元素序列。本章将详细介绍数组的基本概念、创建、遍历、常见操作以及二维数组。
一、数组基本概念
1. 数组定义
程序 = 算法 + 数据结构。
- 算法:解决程序问题的流程步骤。
- 数据结构:将数据按照某种特定的结构来存储。数组是最简单的数据结构之一。
数组是相同数据类型元素的有序集合,在内存中是一块连续的空间,长度一旦创建便不可修改。数组属于引用类型(基本类型数组存储值,引用类型数组存储对象地址),通过下标(索引)访问元素。
2. 数组的创建
数组创建主要有两种方式:
- 静态初始化:在声明数组的同时,直接给出数组元素的初始值。适用于数组元素已知的情况。
int[] array1 = {32, 5, 7, 87}; int[] array2 = new int[]{32, 5, 7, 87}; - 动态初始化:在声明数组时,仅指定数组的长度,然后通过赋值语句逐个给数组元素赋值。适用于数组元素在声明时未知的情况。
元素类型[] 数组名 = new 元素类型[长度]; // 示例 int[] array1 = new int[3]; double[] array2 = new double[4]; // 其他数据类型同上
各类型数组默认初始值:
byte/short/int/long:0float/double:0.0boolean:falsechar:\u0000(空字符)- 引用类型(
String、对象):null
3. 数组的遍历
@Test // 数组的定义和遍历 public void testArray() { int[] array = new int[4]; // new一个对象 array[0] = 123; array[1] = 456; array[2] = 789; array[3] = 101112; System.out.println(array[0]); System.out.println(array[1]); System.out.println(array[2]); System.out.println(array[3]); System.out.println("----------------------"); // 正序遍历 for (int i = 0; i < array.length; i++) { System.out.println(array[i]); } System.out.println("----------------------"); // 倒序遍历 for (int i = array.length - 1; i >= 0; i--) { System.out.println(array[i]); } System.out.println("----------------------"); // 增强的for循环,不需要遍历下标,自动遍历数组中的元素,适用于只需要元素,不需要下标的情况 // 语法:for(数组元素的类型 数组元素的别名 : 数组名){} for (int item : array) { System.out.println(item); } }二、数组下标越界异常
访问数组时,如果下标超出了数组的有效范围(0 到length-1),则会抛出ArrayIndexOutOfBoundsException。
@Test // 数组下标越界异常 public void testArray2() { int[] array = new int[4]; array[0] = 33; array[1] = 2; array[2] = 45; array[3] = 19; for (int i = 0; i <= array.length; i++) { // 错误:i <= array.length 会导致最后一次循环 i=4,越界 // java.lang.ArrayIndexOutOfBoundsException System.out.println(array[i]); } }三、数组累加和、最大值、最小值、冒泡排序
数组最重要的操作就是遍历。只要能遍历所有元素,就可以进行求和、求最值、排序等操作。
1. 数组累加和
@Test // 求数组的和 public void testArray3() { int[] array = {33, 2, 45, 19}; int sum = 0; for (int i = 0; i < array.length; i++) { sum += array[i]; } System.out.println("sum = " + sum); }2. 最大值、最小值
@Test // 求数组中的最大值 public void testArray4() { int[] array = {33, 2, 45, 19}; int max = array[0]; for (int i = 1; i < array.length; i++) { if (array[i] > max) { max = array[i]; } } System.out.println("max = " + max); } @Test // 求数组中的最小值 public void testArray5() { int[] array = {33, 2, 45, 19}; int min = array[0]; for (int i = 0; i < array.length; i++) { if (array[i] < min) { min = array[i]; } } System.out.println("min = " + min); }调用函数求最大最小值:
@Test public void testArray6() { int[] array = {33, 2, 45, 19}; int max = getMax(array); System.out.println("max = " + max); } /** 获取数组中的最大值 @param array 数组 @return 最大值 */ public int getMax(int[] array) { int max = array[0]; for (int i = 1; i < array.length; i++) { if (array[i] > max) { max = array[i]; } } return max; } @Test public void testArray7() { int[] array = {33, 2, 45, 19}; int min = getMin(array); System.out.println("min = " + min); } /** 获取数组中的最小值 @param array 数组 @return 最小值 */ public int getMin(int[] array) { int min = array[0]; for (int i = 1; i < array.length; i++) { if (array[i] < min) { min = array[i]; } } return min; }3. 数组的排序:冒泡排序
排序过程示例:int[] array = {40, 17, 21, 1};目标:{1, 17, 21, 40}
- 第一轮:40冒到最右边
17, 40, 21, 1
17, 21, 40, 1
17, 21, 1, 40 ------- 40 冒出来 - 第二轮:21冒出来
17, 21, 1, 40
17, 1, 21, 40 ------- 21冒出来 - 第三轮:17冒出来
1, 17, 21, 40 ------- 17冒出来
@Test // 冒泡排序 public void testArray8() { int[] array = {33, 2, 45, 19}; sort1(array); for (int i = 0; i < array.length; i++) { System.out.println(array[i]); } } public void sort1(int[] array) { for (int i = 1; i <= array.length - 1; i++) { // i代表第几轮 for (int j = 0; j < array.length - i; j++) { if (array[j] > array[j + 1]) { int temp = array[j]; array[j] = array[j + 1]; array[j + 1] = temp; } } } } @Test public void testArray9() { int[] array2 = {1, 233, 35, 436, 5}; sort2(array2); for (int i = 0; i < array2.length; i++) { System.out.println(array2[i]); } } public void sort2(int[] array2) { for (int i = 1; i <= array2.length - 1; i++) { for (int j = 0; j < array2.length - i; j++) { if (array2[j] > array2[j + 1]) { int temp = array2[j]; array2[j] = array2[j + 1]; array2[j + 1] = temp; } } } }四、数组复制(扩容)
注意:
- 数组最大的缺点:长度固定。
- 数组扩容:就是构造一个更长的新数组,把原数组数据复制到新数组中。
1. System.arraycopy
这是标准且高效的方法,适用于复制数组的部分或全部。
System.arraycopy(原数组, 原数组起始索引, 目标数组, 目标数组起始索引, 复制长度);
@Test // 使用System.arraycopy方法复制数组 public void test1() { String[] original = {"da", "daa", "daaa", "daaaa"}; String[] copy = new String[original.length]; // 复制整个数组 System.arraycopy(original, 0, copy, 0, original.length); // 复制部分数组(仅复制索引1-2的元素) String[] part = new String[2]; System.arraycopy(original, 1, part, 0, 2); System.out.println("完整复制:" + Arrays.toString(copy)); // 结果:[da, daa, daaa, daaaa] System.out.println("部分复制:" + Arrays.toString(part)); // 结果:[daa, daaa] }2. Arrays.copyOf 与 Arrays.copyOfRange
- Arrays.copyOf:复制指定长度(长度不足截断,过长补默认值)
数组类型[] 新数组 = Arrays.copyOf(原数组, 新数组长度); - Arrays.copyOfRange:复制指定范围(从原数组起始索引到结束索引,不包含结束索引)
数组类型[] 新数组 = Arrays.copyOfRange(原数组, 起始索引, 结束索引);
@Test // 使用Arrays.copyOf和Arrays.copyOfRange方法复制数组 public void test2() { int[] original = {10, 20, 30, 40, 50}; // 1. 复制整个数组(新数组长度=原数组) int[] copy1 = Arrays.copyOf(original, original.length); // 2. 复制并扩容(长度6,多余位置补0) int[] copy2 = Arrays.copyOf(original, 6); // 3. 复制指定范围(索引1到4,即元素20、30、40) // [1,4) 左闭右开 int[] copy3 = Arrays.copyOfRange(original, 1, 4); System.out.println("完整复制:" + Arrays.toString(copy1)); // [10, 20, 30, 40, 50] System.out.println("扩容复制:" + Arrays.toString(copy2)); // [10, 20, 30, 40, 50, 0] System.out.println("范围复制:" + Arrays.toString(copy3)); // [20, 30, 40] }3. 手动遍历赋值
通过 for 循环逐个复制数组元素,适合需要自定义复制逻辑(如只复制部分元素)的场景。
@Test // 手动复制数组 public void test3() { int[] original = {1, 2, 3, 4, 5}; int[] copy = new int[original.length]; // 先创建等长的新数组 // 手动循环复制每个元素 for (int i = 0; i < original.length; i++) { copy[i] = original[i]; } System.out.println("原数组:" + Arrays.toString(original)); // [1, 2, 3, 4, 5] System.out.println("复制数组:" + Arrays.toString(copy)); // [1, 2, 3, 4, 5] }五、二维数组(了解)
二维数组的创建和初始化:
int[][] array = {{1, 2}, {2, 3}, {3, 4, 5}}; int[][] array = new int[3][];@Test // 二维数组 public void test4() { int[][] array = new int[3][]; array[0] = new int[2]; array[1] = new int[2]; array[2] = new int[3]; array[0][0] = 23; array[0][1] = 12; array[1][0] = 22; array[1][1] = 22; array[2][0] = 21; array[2][1] = 22; array[2][2] = 23; for (int i = 0; i < array.length; i++) { for (int j = 0; j < array[i].length; j++) { System.out.println(array[i][j]); } } }