数组的定义与使用
1. 数组的定义及声明
数组是一种数据结构,用来存储同一类型值的集合。通过一个整型下标(index,或称索引)可以访问数组中的每一个值。例如,如果A是一个整型数组,那么a[i]就是数组中下标为i的整数。
在声明数组变量时,需要指出数组类型(数据元素类型紧跟[])和数组变量的名字。下面是一个例子:
int [] a;
不过这条语句只声明了变量a,并没有将a初始化为一个真正的数组。应该使用new 操作符来创建数组,如下
int [] a= new int [100]; //var a = new int [100];
这条语句声明并初始化了一个可以存储100个整数的数组。
一旦创建了数组,就不能改变它的长度(但可以改变单个数组元素的内容)。如果程序运行中需要经常扩展数组的大小,就应该使用另一种数据结构——数组列表(ArrayList),有关其内容将在以后提及。
那么如何初始化数组呢?
在Java中,提供了一种创建数组对象并同时提供初始值的简写形式。下面是一个例子:
int [] array = {1,2,3,4,5,6};
请注意,这个语法中不需要使用new关键字,甚至不用指定长度。
最后一个值后面不允许有逗号。如果要不断为数组增加值,这样会很方便,如下
String name ={
"张三",
"李四",
"王五",
//可以在这里添加更多的同类型数据字段
}
还可以声明一个匿名数组,如下所示:
new int [] {1,2,3,4,5};
这会分配一个新数组,并填入到括号中提供的值,它会统计初始值个数,并相应的设置数组大小。可以使用这种语法重新初始化一个数组,而无需创建新变量。如下所示:
int array [] = new int {1,2,3,4,5};
tips: 在Java中,允许有长度为0的数组。在编写一个结果为数组的方法时,如果碰巧结果为空,这样一个长度为零的数组就很有用。但是请注意,长度为零的数组与null并不相同。
2. 数组的使用
int[] array = new int[100];
System.out.println("length: " + array.length);//数组长度可用array(数组名).length获取
我们在创建一个数字数组时,所有的元素都会初始化为0,boolean数组的元素会初始化为false,对象数组的元素则初始化为一个特殊值null,表示这些元素还未存放任何对象。
tips:如果创建了一个100个元素的数组,并且试图访问元素a[100](或者下标不在0~99范围之内。),就会引起==“java.lang.ArrayIndexOutOfBoundsException ”==异常。
如何遍历数组?
所谓 “遍历” 是指将数组中的所有元素都访问一遍, 不重不漏. 通常需要搭配循环语句.
- 普通for循环遍历
int[] arr = {1, 2, 3};
for (int i = 0; i < arr.length; i++)
{
System.out.println(arr[i]);
}// 执行结果 123
-
for each循环
Java有一种功能很强的循环结构。可以用来一次处理数组(或者其他元素集合)中的每个元素,而不必考虑指定的下标值。
这种增强for循环的语句格式为:
for (variable : collection) statement
举例如下:
int[] array = new int[]{1,2,3}; for (int num : array) { System.out.println(num); }
我们可以发现两种方法都可以获得同样效果,但是for each循环显得的更加简洁,更不易出错,因为我们不必为下标的起始值和终止值而操心。
tips:for each循环语句的循环变量将会遍历数组中的每个元素,而不是下标值。
打印数组中所有值的方法
利用Arrays类的toString方法。调用Arrays.toString(array),即可返回一个包含数组元素的字符串,这些元素包括在中括号内,并用逗号分隔,举例如下:
int[] array = new int[]{1,2,3};
System.out.println(Arrays.toString(array));
结果如下:
[1, 2, 3]
3. 数组拷贝
代码示例
int[] arr = {1, 2, 3, 4, 5, 6};
int[] newArr = Arrays.copyOf(arr, arr.length);
System.out.println("newArr: " + Arrays.toString(newArr));
arr[0] = 10;
System.out.println("arr: " + Arrays.toString(arr));
System.out.println("newArr: " + Arrays.toString(newArr));
// 拷贝某个范围.
int[] newArr2 = Arrays.copyOfRange(arr, 2, 4);
System.out.println("newArr2: " + Arrays.toString(newArr2));
注意事项: 相比于 newArr = arr 这样的赋值, copyOf 是将数组进行了 深拷贝, 即又创建了一个数组对象, 拷贝原有
数组中的所有元素到新数组中. 因此, 修改原数组, 不会影响到新数组.
Arrays.copyOf(int[] original, int newLength)
复制指定的数组,截取或用 0 填充(如有必要),以使副本具有指定的长度。对于在原数组和副本中都有效的所有索引,这两个数组将包含相同的值。对于在副本中有效而在原数组无效的所有索引,副本将包含 0。当且仅当指定长度大于原数组的长度时,这些索引存在。
参数: original - 要复制的数组 newLength - 要返回的副本的长度
返回: 原数组的副本,截取或用 0 填充以获得指定的长度
Arrays.copyOfRange(int[] original,int from, int to)
将指定数组的指定范围复制到一个新数组。该范围的初始索引 (from) 必须位于 0 和 original.length(包括)之间。original[from] 处的值放入副本的初始元素中(除非 from == original.length 或 from == to)。原数组中后续元素的值放入副本的后续元素。该范围的最后索引 (to)(必须大于等于 from)可以大于 original.length,在这种情况下,0 被放入索引大于等于 original.length - from 的副本的所有元素中。返回数组的长度为 to - from。
参数:
original - 将要从其复制一个范围的数组
from - 要复制的范围的初始索引(包括)
to - 要复制的范围的最后索引(不包括)。(此索引可以位于数组范围之外)。
返回: 包含取自原数组指定范围的新数组,截取或用 0 填充以获得所需长度
4. 数组排序
要想对数值型数组进行排序,可以使用Arrays类中的sort方法(这个方法使用了优化的快速排序算法。):
int[] arr = {1, 2, 3, 4, 5, 6};
Arrays.sort(arr);
5.多维数组
多维数组将使用多个下周访问数组元素,它适用于表示表格或更加复杂的排列形式。
基本语法
数据类型[][] 数组名称 = new 数据类型 [行数][列数] { 初始化数据 };
代码示例:
public static void main(String[] args)
{
int[][] arr = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
for (int row = 0; row < arr.length; row++)
{
for (int col = 0; col < arr[row].length; col++)
{
System.out.printf("%d\t", arr[row][col]);
}
System.out.println("");
}
// 执行结果
// 1 2 3 4
// 5 6 7 8
// 9 10 11 12
}
tips:要想快速打印一个二维数组元素列表可以调用,Arrays.deepToString(),
其输出格式为:
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
如果想用for each循环语句来打印二维数组,则它需要两个嵌套的循环,代码如下:
int[][] arr = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; for (int[] ints : arr) { for (int anInt : ints) { System.out.printf("%d\t", anInt); } System.out.println(); }
6. 找数组中的最大元素
public static void main(String[] args)
{
int[] arr = {1, 2, 3, 4, 5, 6};
System.out.println(max(arr));
}
public static int max(int[] arr)
{
int max = arr[0];
for (int i = 1; i < arr.length; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
}
return max;
}
// 执行结果 6
7. 查找数组中指定元素(顺序查找)
public static void main(String[] args)
{
int[] arr = {1, 2, 3, 10, 5, 6};
System.out.println(find(arr, 10));
}
public static int find(int[] arr, int toFind)
{
for (int i = 0; i < arr.length; i++)
{
if (arr[i] == toFind)
{
return i;
}
}
return -1; // 表示没有找到
}
8.查找数组中指定元素(二分查找)
前提:数组为有序数组
代码示例:
public static int binarySearch(int[] arr, int num)
{
int left = 0;
int right = arr.length - 1;
while (left <= right)
{
int mid = (left + right) / 2;
if (arr[mid] < num)
{
left = mid + 1;
}
else if (arr[mid] > num)
{
right = mid - 1;
}
else
{
return mid;
}
}
return -1;
}
9. 给定一个整型数组, 将所有的偶数放在前半部分, 将所有的奇数放在数组后半部分
public static void transform(int[] arr)
{
int left = 0;
int right = arr.length - 1;
while (left < right)
{
// 该循环结束, left 就指向了一个奇数
while (left < right && arr[left] % 2 == 0)
{
left++;
}
//该循环结束, right 就指向了一个偶数
while (left < right && arr[right] % 2 != 0)
{
right--;
}
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
}
System.out.println(Arrays.toString(arr));
}