声明数组变量
如同其他使用数据类型使用一样,使用数组必须先声明数组变量,并指明数组的元素类型。声明数组变量的语法:
-
元素类型[] 数组引用变量; (推荐使用这种,阅读感更强)
-
元素类型 数组引用变量[];
举例:
1 int[] arr1; 2 int arr2[];
声明一个数组变量时,并不在内存中给数组分配任何空间。它只是创建一个对数组的引用的存储位置。如果变量不包含对数组的引用,那么这个变量的值为null。除非数组已经被创建,否则不能给它分配任何元素。创建数组的语法:
-
元素类型[] 数组引用变量 = new 元素类型[数组大小];(数组创建但未添加元素)
-
元素类型 数组引用变量[] = new 元素类型[数组大小];(数组创建但未添加元素)
-
元素类型[]数组引用变量 = new 元素类型[];(数组创建同时添加元素)
-
元素类型 数组引用变量[] = new 元素类型[];(数组创建同时添加元素)
举例:
1 int[] arr1 = new int[5]; 2 int arr2[] = new int[5]; 3 int[] arr3 = new int[] {1,2,3,4,5}; 4 int arr4[] = new int[] {1,2,3,4,5};
当给数组分配空间时,必须通过指定该数组能够存储的元素个数来确定数组大小。数组一旦创建,就不能再修改它的大小。可以使用数组.length获得该数组的大小。
当数组创建后,它的元素被赋予默认值,byte、short、int、long型为0,float、double型为0.0,boolean型为false,char型为'\u0000'。
获取数组下标变量
数组元素可以通过下标来访问。数组下标是基于0的,起止范围从0到数组.length-1结束。
处理数组
处理数组的常用举例:
使用输入值初始化数组
1 /** 2 * 循环遍历给数组赋值 3 */ 4 public static void inputNumToArray(int[] array) { 5 Scanner input = new Scanner(System.in); 6 for (int i = 0; i < array.length; i++) { 7 array[i] = input.nextInt(); 8 } 9 }
1 /** 2 * 使用随机数初始化数组 3 */ 4 public static void randomNumToArray(int[] array) { 5 for (int i = 0; i < array.length; i++) { 6 array[i] = (int) (Math.random()*10); 7 System.out.println(array[i]); 8 } 9 }
1 /** 2 * 打印数组中所有元素 3 */ 4 public static void printNumToArray(int[] array) { 5 for (int i = 0; i < array.length; i++) { 6 System.out.println(array[i]); 7 } 8 }
1 /** 2 * 计算数组中所有元素之和 3 */ 4 public static int randomNumToArray(int[] array) { 5 int total = 0; 6 for (int i = 0; i < array.length; i++) { 7 total += array[i]; 8 } 9 return total; 10 }
1 /** 2 * 获取数组中元素最大值 3 */ 4 public static int getMaxNumToArray(int[] array) { 5 int max = array[0]; 6 for (int i = 0; i < array.length; i++) { 7 if (max < array[i]) { 8 max = array[i]; 9 } 10 } 11 return max; 12 }
1 /** 2 * 获取数组中元素最大值的最小角标 3 */ 4 public static int getMaxIndexNumToArray(int[] array) { 5 int max = array[0]; 6 int index = 0; 7 for (int i = 0; i < array.length; i++) { 8 if (max < array[i]) { 9 max = array[i]; 10 index = i; 11 } 12 } 13 return index; 14 }
1 /** 2 * 获取打乱了的数组 3 */ 4 public static int[] randomArrayToArray(int[] array) { 5 int index = 0; 6 int temp = 0; 7 for (int i = 0; i < array.length; i++) { 8 index = (int) (Math.random() * array.length); 9 temp = array[i]; 10 array[i] = array[index]; 11 array[index] = temp; 12 } 13 return array; 14 }
1 /** 2 * 整体左移一位,最左边的移到最右边 3 */ 4 public static int[] startNumToEnd(int[] array) { 5 int temp = array[0]; 6 for (int i = 1; i < array.length; i++) { 7 array[i - 1] = array[i]; 8 } 9 array[array.length - 1] = temp; 10 return array; 11 }
1 /** 2 * 逆向输出数组顺序 3 */ 4 public static int[] backArray(int[] array) { 5 int temp = 0; 6 for (int i = 0; i < array.length / 2; i++) { 7 temp = array[i]; 8 array[i] = array[array.length - 1 - i]; 9 array[array.length - 1 - i] = temp; 10 } 11 return array; 12 }
Java提供一种简便的for循环,称之为for-each循环(for-each loop)或增强for循环(enhanced for loop),不使用下标变量就可以顺序的遍历整个数组。语法如下:
for (元素类型 元素 : 数组) {
}
但是,当需要以其他顺序遍历数组或改变数组中的元素时,还是必须使用下标变量。
值传递
一个对象变量并没有实际包含一个对象,而仅仅引用了一个对象。该变量不会自动初始化为null,而是必须通过调用new或将它们设置为null进行初始化。
Java总是采用值调用,也就是说,方法得到的是所有参数值的一个拷贝,特别是,方法不能修改传递给它的任何参数变量的内容。例如基本数据类型:
1 public static void main(String[] args) { 2 int a = 30; 3 updateNum(a); 4 System.out.println("a =" + a); 5 } 6 public static void updateNum(int b) { 7 b = 20; 8 System.out.println("b =" + b); 9 } 10 console: 11 b = 20 12 a = 30
-
程序将变量a的副本传递到updateNum()方法。
-
在updateNum()方法内,对变量a的副本进行了修改,但并未对变量a进行修改。
-
当程序执行完updateNum()方法后,变量a副本的值为30,最后副本被抛弃。
-
程序回到main函数,继续执行真正的变量a。
可以看到main方法下的num打印结果不变依旧3o。一个方法不可能修改一个基本数据类型的参数。而引用数据类型作为参数就不同了。引用数据类型:
1 public static void main(String[] args) { 2 int[] arrA = new int[1]{30}; 3 updateArrNum(arrA); 4 System.out.println("arrA[0] =" + arrA[0]); 5 } 6 public static void updateArr(int[] arrB) { 7 arrB[0] = 20; 8 System.out.println("arrB[0] =" + arrB[0]); 9 } 10 console: 11 arrB[0] = 20 12 arrA[0] = 20
-
程序将数组arrA引用的副本传递给updateArr()方法。
-
在updateArr()方法内,对数组arrA引用的副本进行了重新赋值值。注意:虽然是对副本进行重新赋值,但是arrA与arrA的副本引用的是同一块内存地址。
-
当重新赋值时,原始的arrA的值也变了。
更多时候数组的复制,并不希望对内存地址的复制,而是希望对数组中的元素进行复制。通常可以使用循环遍历,逐个对元素进行复制。示例如下:
1 public static void main(String[] args) { 2 int[] arrA = new int[5]{10, 20, 30, 40, 50}; 3 int[] arrB = new int[arrA.length]; 4 for (int i = 0; i < arrA.length, i++) { 5 arrB[i] = arrA[i]; 6 } 7 }
查找(searching)是在数组中寻找特定元素的过程。常用的查找有线性查找(linear searching)和二分查找(binary searching)。
线性查找
线性查找将要查找的关键字key与数组中的元素逐个进行比较。这个过程持续到在列表中找到与关键字匹配的元素,或者查完列表也没找到关键字为止。如果匹配成功,返回与关键字匹配的元素在数组中的下标。如果没有匹配成功,则返回-1。线性查找示例如下:
1 public int linearSearching(int[] arr, int key) { 2 for (int i = 0; i < arr.length; i++) { 3 if (arr[i] == key) { 4 return i; 5 } 6 return -1; 7 } 8 }
二分查找法
使用二分查找法的前提条件是数组中的元素必须已经排好序。假设数组已按升序排列,二分查找法首先将关键字与数组的中间元素进行比较。主要考虑三种情况:
-
如果关键字小于中间元素,只需要在数组的前一半元素中继续查找关键字。
-
如果关键字和中间元素相等,则匹配成功,查找结束。
-
如果关键字大于中间元素,只需要在数组的后一半元素中继续查找关键字。
实现思路:每次比较后,数组要查找的部分就会缩小一半。用low和high分别表示当前查找数组的第一个下标和最后一个下标。初始条件下,low为0,而high为list.length-1。让mid表示列表的中间元素的下标。这样,mid就是(low + high) /2 。如果找到这个关键字,或者当low>high时还没有找到这个关键字,就结束查找。二分查找示例如下:
1 public int binarySearch(int[] array, int key) { 2 //设置数组元素最小角标 3 int low = 0; 4 //设置数组元素最大角标 5 int high = array.length - 1; 6 //设置数组元素中间角标 7 int mid = 0; 8 while (high >= low) { 9 mid = (low + high) / 2; 10 if (array[mid] < key) { 11 low = mid + 1; 12 } else if (array[mid] == key) { 13 return mid; 14 } else { 15 high = mid - 1; 16 } 17 } 18 return -1; 19 }
数组的排序
数组的排序有多种方法,比较简单、直观的排序算法有:选择排序法(selection sort)和插入排序法(insertion sort)。
选择排序
假设要按照从小到大排列一个数列。选择排序法先找到数列中最小的数,然后将它放在数列的最前面。接下来,在剩下的数中找到最小数,将它放到第一个数的后面,以此类推,知道数列中仅剩一数为止。选择排序示例如下:
1 public static int[] selectionSort(int[] array) { 2 for (int i = 0; i < array.length - 1; i++) {//倒数第二次已经找到所有位置,不需要进行最后一次遍历 3 for (int j = i + 1; j < array.length; j++) {//一旦位置找到,下一次遍历是就不需要再考虑它原有位置 4 if (array[i] > array[j]) { 5 int temp = array[i]; 6 array[i] = array[j]; 7 array[j] = temp; 8 } 9 } 10 } 11 }
冒泡排序算法在每次遍历中,对相邻的两个元素进行比较。如果这一对元素是降序,则交换它们的值,否则,保持值不变。由于较小的值像气泡一样逐渐“浮向”顶部,同时较大的值“沉向”底部,所以这种技术称为冒泡排序法(bubble sort)。冒泡排序示例如下:
1 public static int[] bubbling(int[] array) { 2 for (int i = 0; i < array.length - 1; i++) { 3 for (int j = 0; j < array.length - i - 1; j++) {//随着每次冒泡,递减对比 4 if (array[j] > array[j+1]) {//当小于数组前面的元素大于后面的元素时,交换位置 5 int temp = array[j]; 6 array[j] = array[j+1]; 7 array[j+1] = temp; 8 } 9 } 10 } 11 return array; 12 }
浙公网安备 33010602011771号