数组的基本操作

java.util 包的 Arrays 类中包含了用来操作数组(如排序和搜索)的各种方法,本节将讲解数组的基本操作。

遍历数组

遍历数组就是获取数组中的每个元素。通常遍历数组都是使用 for 循环来实现的。遍历一维数组很简单,也很好理解,下面详细介绍遍历二维数组的方法。

遍历二维数组需使用双层 for 循环,通过数组的 length 属性可获得数组的长度。

【例5.3】呈梯形输出二维数组中的元素(实例位置:资源包\TM\sl\5\3)

在项目中创建 Trap 类,在主方法中编写代码,定义二维数组,将二维数组中的元素呈梯形进行输出。实例代码如下:

public class Trap { // 创建类
	public static void main(String[] args) { // 主方法
		int b[][] = new int[][] { { 1 }, { 2, 3 }, { 4, 5, 6 } }; // 定义二维数组
		for (int k = 0; k < b.length; k++) {
			for (int c = 0; c < b[k].length; c++) { // 循环遍历二维数组中的每个元素
				System.out.print(b[k][c]); // 将数组中的元素输出
			}
			System.out.println(); // 输出空格
		}
	}
}

运行结果如下:

     1
     23
     456

在遍历数组时,使用 foreach 语句可能会更简单。下面的实例就是通过 foreach 语句遍历二维数组的。

【例5.4】使用 foreach 语句遍历二维数组(实例位置:资源包\TM\sl\5\4)

在项目中创建 Tautog 类,在主方法中定义二维数组,使用 foreach 语句遍历二维数组。实例代码如下:

public class Tautog { // 创建类
	public static void main(String[] args) { // 主方法
		int arr2[][] = { { 4, 3 }, { 1, 2 } }; // 定义二维数组
		System.out.println("数组中的元素是:"); // 提示信息
		int i = 0; // 外层循环计数器变量
		for (int x[] : arr2) { // 外层循环变量为一维数组
			i++; // 外层计数器递增
			int j = 0; // 内层循环计数器
			for (int e : x) { // 循环遍历每一个数组元素
				j++; // 内层计数器递增
				if (i == arr2.length && j == x.length) { // 判断变量是二维数组中的最后一个元素
					System.out.print(e); // 输出二维数组的最后一个元素
				} else
					// 如果不是二维数组中的最后一个元素
					System.out.print(e + "、"); // 输出信息
			}
		}
	}
}

运行结果如下:

     数组中的元素是:
     4、3、1、2

填充替换数组元素

数组中的元素被定义完成后,可通过 Arrays 类的静态方法 fill() 来对数组中的元素进行替换。该方法通过各种重载形式可完成对任意类型的数组元素的替换。fill() 方法有两种参数类型,下面以 int 型数组为例讲解 fill() 方法的使用方法。

fill(int[] a,int value)

该方法可将指定的 int 值分配给 int 型数组的每个元素。语法如下:

fill(int[] a, int value)
  • a:要进行元素替换的数组。

  • value:要存储数组中所有元素的值。

【例5.5】使用 fill() 方法填充数组元素(实例位置:资源包\TM\sl\5\5)

在项目中创建 Swap 类,在主方法中创建一维数组,并实现通过 fill() 方法填充数组元素,最后将数组中的各个元素进行输出。实例代码如下:

import java.util.Arrays; //导入java.util.Arrays类

public class Swap { // 创建类
	public static void main(String[] args) { // 主方法
		int arr[] = new int[5]; // 创建int型数组
		Arrays.fill(arr, 8); // 使用同一个值对数组进行填充
		for (int i = 0; i < arr.length; i++) { // 循环遍历数组中的元素
			// 将数组中的元素依次输出
			System.out.println("第" + i + "个元素是:" + arr[i]);
		}
	}
}

运行结果如下:

     第0个元素是:8
     第1个元素是:8
     第2个元素是:8
     第3个元素是:8
     第4个元素是:8

fill(int[] a,int fromIndex,int toIndex,int value)

该方法将指定的 int 值分配给 int 型数组指定范围中的每个元素。填充的范围从索引 fromIndex(包括)一直到索引 toIndex(不包括)。如果 fromIndex ==toIndex,则填充范围为空。语法如下:

fill(int[] a, int fromIndex, int toIndex, int value)
  • a:要进行填充的数组。

  • fromIndex:要使用指定值填充的第一个元素的索引(包括)。

  • toIndex:要使用指定值填充的最后一个元素的索引(不包括)。

  • value:要分配给数组指定范围中的每个元素的值。

如果指定的索引位置大于或等于要进行填充的数组的长度,则会报出 ArrayIndexOutOf-BoundsException(数组越界异常,关于异常的知识将在后面的章节中进行讲解)异常。

【例5.6】使用 fill() 方法替换数组中的元素(实例位置:资源包\TM\sl\5\6)

在项目中创建 Displace 类,在主方法中创建一维数组,并通过 fill() 方法替换数组元素,最后将数组中的各个元素进行输出。实例代码如下:

import java.util.Arrays; //导入java.util.Arrays类

public class Displace { // 创建类
	public static void main(String[] args) { // 主方法
		int arr[] = new int[] { 45, 12, 2, 10 }; // 定义并初始化int型数组arr
		Arrays.fill(arr, 1, 2, 8); // 使用fill()方法对数组进行初始化
		for (int i = 0; i < arr.length; i++) { // 循环遍历数组中的元素
			// 将数组中的每个元素输出
			System.out.println("第" + i + "个元素是:" + arr[i]);
		}
	}
}

运行结果如下:

     第0个元素是:45
     第1个元素是:8
     第2个元素是:2
     第3个元素是:10

对数组进行排序

通过 Arrays 类的静态方法 sort() 可以实现对数组的排序。sort() 方法提供了多种重载形式,可对任意类型的数组进行升序排序。语法如下:

Arrays.sort(object)

其中,object 是指进行排序的数组名称。

【例5.7】使用 sort() 方法将数组排序后进行输出(实例位置:资源包\TM\sl\5\7)

在项目中创建 Taxis 类,在主方法中创建一维数组,将数组排序后进行输出。实例代码如下:

import java.util.Arrays; //导入java.util.Arrays类

public class Taxis { // 创建类
	public static void main(String[] args) { // 主方法
		int arr[] = new int[] { 23, 42, 12, 8 }; // 声明数组
		Arrays.sort(arr); // 将数组进行排序
		for (int i = 0; i < arr.length; i++) { // 循环遍历排序后的数组
			System.out.println(arr[i]); // 将排序后数组中的各个元素输出
		}
	}
}

运行结果如下:

     8
     12
     23
     42

上述实例是对整型数组进行排序的。Java 中的 String 类型数组的排序算法是根据字典编排顺序排序的,因此数字排在字母前面,大写字母排在小写字母前面。

复制数组

Arrays 类的 copyOf() 方法与 copyOfRange() 方法可以实现对数组的复制。copyOf() 方法是复制数组至指定长度,copyOfRange() 方法则将指定数组的指定长度复制到一个新数组中。

copyOf()方法

该方法提供了多种重载形式,用于满足不同类型数组的复制。语法如下:

copyOf(arr,int newlength)
  • arr:要进行复制的数组。

  • newlength:int型常量,指复制后的新数组的长度。如果新数组的长度大于数组 arr 的长度,则用 0 填充(根据复制数组的类型来决定填充的值,整型数组用 0 填充,char 型数组则使用 null 来填充);如果新数组长度小于数组 arr 的长度,则会从数组 arr 的第一个元素开始截取至满足新数组长度为止。

【例5.8】复制数组(实例位置:资源包\TM\sl\5\8)

在项目中创建 Cope 类,在主方法中创建一维数组,实现将此数组进行复制以得到一个长度为 5 的新数组,并将新数组进行输出。实例代码如下:

import java.util.Arrays; //导入java.util.Arrays类

public class Cope { // 创建类
	public static void main(String[] args) { // 主方法
		int arr[] = new int[] { 23, 42, 12 }; // 定义数组
		int newarr[] = Arrays.copyOf(arr, 5); // 复制数组arr
		for (int i = 0; i < newarr.length; i++) { // 循环变量复制后的新数组
			System.out.println(newarr[i]); // 将新数组输出
		}
	}
}

运行结果如下:

     23
     42
     12
     0
     0

copyOfRange()方法

该方法同样提供了多种重载形式。语法如下:

copyOfRange(arr, int formIndex, int toIndex)
  • arr:要进行复制的数组对象。

  • formIndex:指定开始复制数组的索引位置。formIndex 必须在 0 至整个数组的长度之间。新数组包括索引是 formIndex 的元素。

  • toIndex:要复制范围的最后索引位置。可大于数组 arr 的长度。新数组不包括索引是 toIndex 的元素。

【例5.9】按照索引复制数组(实例位置:资源包\TM\sl\5\9)

在项目中创建 Repeat 类,在主方法中创建一维数组,并将数组中索引位置是 0~3 的元素复制到新数组中,最后将新数组进行输出。实例代码如下:

import java.util.Arrays; //导入java.util.Arrays

public class Repeat { // 创建类
	public static void main(String[] args) { // 主方法
		int arr[] = new int[] { 23, 42, 12, 84, 10 }; // 定义数组
		int newarr[] = Arrays.copyOfRange(arr, 0, 3); // 复制数组
		for (int i = 0; i < newarr.length; i++) { // 循环遍历复制后的新数组
			System.out.println(newarr[i]); // 将新数组中的每个元素输出
		}
	}
}

运行结果如下:

     23
     42
     12

查询数组

Arrays 类的 binarySearch() 方法,可使用二分搜索法来搜索指定数组,以获得指定对象。该方法返回要搜索元素的索引值。binarySearch() 方法提供了多种重载形式,用于满足各种类型数组的查找需要。binarySearch() 方法有两种参数类型。

binarySearch(Object[] a, Object key)

语法如下:

binarySearch(Object[] a, Object key)
  • a:要搜索的数组。

  • key:要搜索的值。

如果 key 被包含在数组中,则返回搜索值的索引;否则返回 -1 或 “-”(插入点)。插入点是搜索键将要被插入数组中的那一点,即第一个大于此键的元素索引。

必须在调用 binarySearch(Object[] a, Object key) 之前对数组进行排序(通过 sort() 方法)。如果没有对数组进行排序,则结果是不确定的。如果数组包含多个带有指定值的元素,则无法保证找到的是哪一个。

【例5.10】查找元素在数组中的索引位置(实例位置:资源包\TM\sl\5\10)

在项目中创建 Reference 类,在主方法中创建一维数组 ia,实现查找元素 4 在数组 ia 中的索引位置。实例代码如下:

import java.util.Arrays; //导入java.util.Arrays类

public class Example { // 创建类
	public static void main(String[] args) { // 主方法
		int ia[] = new int[] { 1, 8, 9, 4, 5 }; // 定义int型数组ia
		Arrays.sort(ia); // 将数组进行排序
		int index = Arrays.binarySearch(ia, 4); // 查找数组ia中元素4的索引位置
		System.out.println("4的索引位置是:" + index); // 将索引输出
	}
}

运行结果如下:

     4的索引位置是:1

返回值 “1” 是对数组 ia 进行排序后元素 4 的索引位置。

binarySearch(Object[],a,int fromIndex,int toIndex,Object key)

该方法在指定的范围内检索某一元素。语法如下:

binarySearch(Object[] a, int fromIndex, int toIndex, Object key)
  • a:要进行检索的数组。

  • fromIndex:指定范围的开始处索引(包含)。

  • toIndex:指定范围的结束处索引(不包含)。

  • key:要搜索的元素。

在使用该方法前,同样要对数组进行排序,这样才能获得准确的索引值。如果要搜索的元素 key 在指定的范围内,则返回搜索键的索引;否则返回 -1 或 “-”(插入点)。如果范围中的所有元素都小于指定的键,则插入点为 toIndex(注意,这保证了当且仅当此键被找到时,返回的值将大于或等于 0)。

如果指定的范围大于或等于数组的长度,则会报出 ArrayIndexOutOfBoundsException 异常。

【例5.11】在指定范围内查找元素在数组中的索引位置(实例位置:资源包\TM\sl\5\11)

在项目中创建 Rakel 类,在主方法中创建 String 数组,实现在指定范围内查找元素 “cd” 在数组 str 中的索引位置。实例代码如下:

import java.util.Arrays; //导入java.util.Arrays类

public class Rakel { // 创建类
	public static void main(String[] args) { // 主方法
		// 定义String型数组str
		String str[] = new String[] { "ab", "cd", "ef", "yz" };
		Arrays.sort(str); // 将数组进行排序
		// 在指定的范围内搜索元素“cd”的索引位置
		int index = Arrays.binarySearch(str, 0, 2, "cd");
		System.out.println("cd的索引位置是:" + index); // 将索引输出
	}
}

运行结果如下:

     cd的索引位置是:1

编程训练(答案位置:资源包\TM\sl\5\编程训练)

【训练5】鸡蛋装箱(一) 某鸡蛋公司准备好10个包装箱,每箱装60枚鸡蛋。由于机器故障,每箱少装了2枚鸡蛋,使用数组的相关知识体现该过程。

【训练6】鸡蛋装箱(二) 某鸡蛋公司准备好10个包装箱,每箱装60枚鸡蛋。由于机器故障,后6箱少装了2枚鸡蛋,使用数组的相关知识体现该过程。