数组的概念
1.1 什么是数组
数组是由相同类型元素构成的集合,这些元素在内存中连续存储。定义一个数组相当于一次性定义了多个变量,这些变量具有相同的数据类型,并通过下标进行访问。数组的基本特性:
• 数组中存放的是一个或多个数据,但元素个数不能为0
• 数组中存放的多个数据,类型是相同的
• 数组在内存中是连续存放的
• 数组的大小在创建时确定,大小不可改变
1.2 什么是数组元素
构成数组的每一个数据称为数组元素。数组元素可以是基本数据类型(如int、double、char)也可以是引用类型(如对象)。1.3 什么是数组下标
数组的下标是元素在数组中的位置索引,从0开始,依次累加1。下标的界限是:0 ~ 数组长度-1。如果访问数组时下标 <0 或 >数组长度-1,会抛出ArrayIndexOutOfBoundsException异常。
1.4 什么是数组长度
数组长度表示数组的大小,即数组元素的个数。获取数组长度的方法是:数组名.length。注意:数组的大小在分配内存时就已经确定,大小不可改变。
数组的声明和创建(以一维数组为例)
2.1 定义数组
// 数组名在前int arr1[];
// 数组名在后int[] arr2;
2.2 为数组元素分配内存空间// 一种方法 int arr1[] = new int[5]; // 另一种方法 double[] arr2; arr2 = new double[4]; new运算符用于为数组元素分配内存,数据类型必须相同。
2.3 数组元素初始化
// 第一种写法:动态初始化 int arr1[] = new int[]{ 1, 2, 3, 4, 5 }; // int[]中括号内不可以写数组的大小 // 第二种写法:静态初始化简化形式 int arr2[] = { 1, 2, 3 }; // 第三种写法:分步初始化 double[] arr3; arr3 = new double[]{ 1.0, 2.1, 3.2, 4.4 }; // 第四种写法:逐个元素初始化 char []ch4 = new char[4]; ch4[0] = 'v'; ch4[1] = 'h'; ch4[2] = 'n'; ch4[3] = 'm'; // 这种写法数组的下标一定不能发生越界
数组初始化时,如果没有给定初始值,数组元素会有其默认值:
• 整型默认值为0
• 浮点型默认值为0.0
• 布尔型默认值为false
• 引用类型默认值为null
2.4 数组元素在内存中的表现形式
当执行int[] score = new int[5]时:• score中存放的是一个引用类型的值(如0xAA01)
• 这个值是一个指针,指向内存中首地址为0xAA01、长度为5的连续内存空间
• 由于没有对数组元素初始化,所有元素使用默认值0
数组的使用
3.1 找数组元素的最大(小)值,求总和,求平均public static void main(String[] args){ int[] arr = new int[]{ 23, 34, 54, 13, 45 }; int max = arr[0]; int min = arr[0]; int sum = 0; for(int i = 1; i < arr.length; i++){ if(max < arr[i]){ max = arr[i]; } if(min > arr[i]){ min = arr[i]; } sum += arr[i]; } System.out.println("最大值为:" + max); System.out.println("最小值为:" + min); System.out.println("总和为:" + sum); System.out.println("平均值为:" + (double)sum/arr.length); }
3.2 对数组排序
3.2.1 冒泡排序public static void main(String[] args) { int score[] = new int[80000]; Random random = new Random(); for (int i = 0; i < score.length; i++) { score[i] = random.nextInt(80000); } long start = System.currentTimeMillis(); // 冒泡排序 for (int i = 0; i < score.length-1; i++) { for (int j = 0; j < score.length-i-1; j++) { if(score[j] > score[j+1]){ int tmp = score[j]; score[j] = score[j+1]; score[j+1] = tmp; } } } long end = System.currentTimeMillis(); System.out.println("耗时:" + (end-start) + "毫秒"); }
结果:80000个数使用冒泡排序大约用时8450毫秒
3.2.2 选择排序
public static void main(String[] args) { int[] arr = new int[80000]; Random r = new Random(); for (int i = 0; i < arr.length; i++) { arr[i] = r.nextInt(80000); } long start = System.currentTimeMillis(); // 选择排序 for (int i = 0; i < arr.length-1; i++) { int minIndex = i; int min = arr[i]; for(int j = i+1; j < arr.length; j++){ if (arr[j] < min){ min = arr[j]; minIndex = j; } } int tmp = arr[i]; arr[i] = arr[minIndex]; arr[minIndex] = tmp; } long end = System.currentTimeMillis(); System.out.println("耗时:" + (end-start) + "毫秒"); }
结果:80000个数使用选择排序大约用时1800毫秒
3.2.3 插入排序
public static void main(String[] args) { int[] arr = new int[80000]; for (int i = 0; i < 80000; i++) { arr[i] = (int)(Math.random() * 80000); } long start = System.currentTimeMillis(); // 插入排序 for (int i = 1; i < arr.length; i++) { int j = i; while (j > 0){ if (arr[j] < arr[j-1]){ int temp = arr[j]; arr[j] = arr[j-1]; arr[j-1] = temp; j--; } else { break; } } } long end = System.currentTimeMillis(); System.out.println("耗时:" + (end-start) + "毫秒"); }
结果:80000个数使用插入排序大约用时700毫秒
3.2.4 快速排序
public static void main(String[] args){ int[] arr = new int[80000]; for (int i = 0; i < 80000; i++) { arr[i] = (int)(Math.random() * 800000); } long s = System.currentTimeMillis(); quickSort(arr, 0, arr.length-1); long e = System.currentTimeMillis(); System.out.println("耗时:" + (e-s) + "毫秒"); } public static void quickSort(int[] arr, int first, int last){ if (first >= last) { return; } int low = first; int high = last; int mid_value = arr[first]; while (low < high){ while (low < high && arr[high] >= mid_value){ high -= 1; } arr[low] = arr[high]; while (low < high && arr[low] < mid_value){ low += 1; } arr[high] = arr[low]; } arr[high] = mid_value; quickSort(arr, first, low-1); quickSort(arr, low+1, last); }
结果:80000个数使用快速排序大约用时20毫秒
Arrays类
4.1 什么是Arrays类
Arrays类是Java提供的数组工具类(java.util.Arrays),包含各种操作数组的静态方法。由于数组本身没有提供很多操作方法,Arrays类填补了这一空白。
4.2 常用方法
4.2.1 查找数组元素:binarySearch方法public static void main(String[] args){ int[] arr = new int[] { 10, 50, 40, 30 }; Arrays.sort(arr); // 排序后:10, 30, 40, 50 int index = Arrays.binarySearch(arr, 10); System.out.println(index); // 0 index = Arrays.binarySearch(arr, 0); System.out.println(index); // -1 index = Arrays.binarySearch(arr, 45); System.out.println(index); // -4 index = Arrays.binarySearch(arr, 90); System.out.println(index); // -5 }
binarySearch方法使用二分查找算法,前提是数组必须已排序。
4.2.2 数组转字符串:Arrays.toString(array)
public static void main(String[] args){ int[] arr1 = { 10, 50, 40, 30, 89, 67, 4, 678 }; Arrays.sort(arr1); System.out.println(Arrays.toString(arr1)); // 输出:[4, 10, 30, 40, 50, 67, 89, 678] }
4.2.3 填充数组:Arrays.fill(array, val)
public static void main(String[] args){ int[] arr1 = { 10, 50, 40, 30, 89, 67, 4, 678 }; Arrays.fill(arr1, 30); System.out.println(Arrays.toString(arr1)); // 输出:[30, 30, 30, 30, 30, 30, 30, 30] }
4.2.4 数组的比较:Arrays.equals(array1, array2)
public static void main(String[] args) { int[] arr1 = { 10, 50, 40, 30 }; int[] arr2 = { 10, 50, 40, 30 }; int[] arr3 = { 60, 50, 85 }; System.out.println(Arrays.equals(arr1, arr2)); // true System.out.println(Arrays.equals(arr1, arr3)); // false }
4.2.5 数组的排序:Arrays.sort(array)
// 数组全部排序public static void main(String[] args){ int[] arr1 = { 10, 50, 40, 30 }; Arrays.sort(arr1); System.out.println(Arrays.toString(arr1)); // 输出:[10, 30, 40, 50] } // 指定范围排序 public static void main(String[] args){ int[] arr1 = { 10, 50, 40, 30, 89, 67, 4, 678 }; Arrays.sort(arr1, 3, arr1.length-1); System.out.println(Arrays.toString(arr1)); // 输出:[10, 50, 40, 4, 30, 67, 89, 678] }
4.2.6 数组的复制:Arrays.copyOf(array, length)
public static void main(String[] args){ int[] arr1 = new int[] { 10, 50, 40, 30 }; // 将arr1复制成长度为3的新数组arr2 int[] arr2 = Arrays.copyOf(arr1, 3); System.out.println(Arrays.toString(arr2)); // [10, 50, 40] }
多维数组(以二维数组为例)
5.1 定义数组
// 数组名在前int arr1[][];
// 数组名在后
int[][] arr2;
5.2 为数组元素分配内存空间
// 一种方法int arr1[][] = new int[5][4];
// 另一种方法
double[][] arr2; arr2 = new double[5][4];
多维数组是"数组的数组",二维数组是最常见的多维数组,可以理解为表格或矩阵。
5.3 数组元素初始化
// 第一种写法 int arr1[][] = new int[][] { {1, 5}, {2, 4, 2}, {3, 7, 9, 5} }; // 第二种写法 int arr2[][] = { {1, 5}, {2, 4, 2}, {3, 7, 9, 5} }; // 第三种写法 double[][] arr3; arr3 = new double[][] { {1.0, 5.1}, {2.2, 4.3, 2.4}, {3.5, 7.6, 9.7, 5.8} }; // 第四种写法:逐个元素初始化 char[][] ch4 = new char[3][2]; ch4[0][0] = 'v'; ch4[0][1] = 'h'; // ... ch4[2][0] = 'h'; ch4[2][1] = 'm';
注意:Java中的多维数组实际上是"不规则数组",每个子数组的长度可以不同。
5.4 多维数组的应用场景
多维数组常用于以下场景:• 图像处理(像素矩阵)
• 游戏开发(地图、棋盘)
• 数学计算(矩阵运算)
• 数据分析(表格数据)
• 科学计算(三维坐标)