目录
4.1 数组的概述
在某些情况下,虽然可以使用单个变量来存储信息,但是如果需要存储的信息较多(例如存储 50 名学生的成绩),这时再依次创建变量声明并赋值显得非常麻烦。
随着处理的信息量越来越大,工作也就越来越烦琐,这时可以使用数组或集合来存储信息。通过使用数组,可以在很大程度上缩短和简化程序代码,从而提高应用程序的效率。
数组(array)是一种最简单的复合数据类型,它是有序数据的集合,数组中的每个元素具有相同的数据类型,可以用一个统一的数组名和不同的下标来确定数组中唯一的元素。根据数组的维度,可以将其分为一维数组、二维数组和多维数组等。
在计算机语言中数组是非常重要的集合类型,大部分计算机语言中数组具有如下三个基本特性:
一致性:数组只能保存相同数据类型元素,元素的数据类型可以是任何相同的数据类型。
有序性:数组中的元素是有序的,通过下标访问。
不可变性:数组一旦初始化,则长度(数组中元素的个数)不可变。
总的来说,数组具有以下特点:
数组可以是一维数组、二维数组或多维数组。
数值数组元素的默认值为 0,而引用元素的默认值为 null。
数组的索引从 0 开始,如果数组有 n 个元素,那么数组的索引是从 0 到(n-1)。
数组元素可以是任何类型,包括数组类型。
数组类型是从抽象基类 Array 派生的引用类型。
注意:如果你熟悉 C/C++,请注意,Java 数组的工作原理与它们不同。
在 Java 中数组的下标是从零开始的,很多计算机语言的数组下标也从零开始。Java 数组下标访问运算符是中括号,如 intArray[0],表示访问 intArray 数组的第一个元素,0 是第一个元素的下标。Java 中的数组本身是引用数据类型,它的长度属性是 length。
4.2 一维数组
- 数组名字为一个合法的标识符,符号“[ ]”指明该变量是一个数组类型变量。单个“[ ]”表示要创建的数组是一个一维数组。
4.21 创建一维数组
- 声明一维数组有两种方式:
-
int [ ] a ; //数组元素类型[ ] 数组名字
int a [ ] ; //数组元素类型 数组名字
- 声明一维数组,语法如下:
-
int arr [ ];//声明int型数组,数组中的每个元素都是int型数值
double[ ] dou;//声明double型数组,数组中的每个元素都是double型数组
数据类型[ ] 数组名 = new 数据类型[数组长度];
int[ ] a = new int [ 5 ];
4.2.2初始化一维数组
- 数组的初始化可分别初始化数组中的每个元素。数组的初始化有以下3种方式;
-
int a [ ] = { 1,2,3 } ; //第一种方式
int b [ ] = new int [ ] { 4,5,6 } ;//第二种方式
int c [ ] = new int [ ] ; //第三种方式
c [ 0 ] = 7 ; //给第一个元素赋值
c [ 1 ] = 8 ; //给第一个元素赋值
c [ 2 ] = 9; //给第一个元素赋值
注意:Java中的数组第一个元素,索引是以0开始的。
4.2.3 获取数组长度
- arr . length
- arr :数组名。
- length:数组长度属性,返回int值
4.2.4 使用一维数组
- 在Java中,一维数组是最常见的一种数据结构。
import java.util.Scanner; public class Test { public static void main(String[] args) { int[] prices = new int[5]; // 声明数组并分配空间 Scanner input = new Scanner(System.in); // 接收用户从控制台输入的数据 for (int i = 0; i < prices.length; i++) { System.out.println("请输入第" + (i + 1) + "件商品的价格:"); prices[i] = input.nextInt(); // 接收用户从控制台输入的数据 } System.out.println("第 3 件商品的价格为:" + prices[2]); } }
4.3二维数组
-
在 Java 中二维数组被看作数组的数组,即二维数组为一个特殊的一维数组,其每个元素又是一个一维数组。Java 并不直接支持二维数组,但是允许定义数组元素是一维数组的一维数组,以达到同样的效果。
type arrayName[][]; // 数据类型 数组名[][];
4.3.1创建二维数组
int[ ] [ ] age;
char[ ] [ ] sex;
4.3.2初始化二维数组
type[][] arrayName = new type[][]{值 1,值 2,值 3,…,值 n}; // 在定义时初始化
type[][] arrayName = new type[size1][size2]; // 给定空间,在赋值
type[][] arrayName = new type[size][]; // 数组第二维长度为空,可变化
有如上3种方式
int[][] temp = new int[][]{{1,2},{3,4}};
4.3.3使用二维数组
public class Test11 {
public static void main(String[] args) {
// 创建一个二维矩阵
int[][] matrix = new int[5][5];
// 随机分配值
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
matrix[i][j] = (int) (Math.random() * 10);
}
}
System.out.println("下面是程序生成的矩阵\n");
// 遍历二维矩阵并输出
for (int k = 0; k < matrix.length; k++) {
for (int g = 0; g < matrix[k].length; g++) {
System.out.print(matrix[k][g] + "");
}
System.out.println();
}
}
}
4.4 数组的基本操作
4.4.1 遍历数组
遍历数组就是获取数组中的每个元素。通常遍历数组都是使用for循环来实现的。遍历二维数组需使用双层for循环,通过数组的length属性可获得数组的长度。
Java 的数组要求所有的数组元素具有相同的数据类型。因此,在一个数组中,数组元素的类型是唯一的,即一个数组里只能存储一种数据类型的数据,而不能存储多种数据类型的数据。
因为 Java 语言是面向对象的语言,而类与类之间可以支持继承关系(从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为),这样可能产生一个数组里可以存放多种数据类型的假象。例如有一个水果数组,要求每个数组元素都是水果,实际上数组元素既可以是苹果,也可以是香蕉(苹果、香蕉都继承了水果,都是一种特殊的水果),但这个数组的数组元素的类型还是唯一的,只能是水果类型。
一旦数组的初始化完成,数组在内存中所占的空间将被固定下来,因此数组的长度将不可改变。即使把某个数组元素的数据清空,但它所占的空间依然被保留,依然属于该数组,数组的长度依然不变。
Java 的数组既可以存储基本类型的数据,也可以存储引用类型的数据,只要所有的数组元素具有相同的类型即可。
值得指出的是,数组也是一种数据类型,它本身是一种引用类型。例如 int 是一个基本类型,但 int[](这是定义数组的一种方式)就是一种引用类型了。
int[] 是一种类型吗?怎么使用这种类型呢?
没错,int[] 就是一种数据类型,与 int 类型、String 类型相似,一样可以使用该类型来定义变量,也可以使用该类型进行类型转换等。使用 int[] 类型来定义变量、进行类型转换时与使用其他普通类型没有任何区别。int[] 类型是一种引用类型,创建 int[] 类型的对象也就是创建数组,需要使用创建数组的语法。
for ( int i =0;i< 数组名.length;i++ ) {
数据类型 a =数组名[ i ];
}
4.4.2 填充和批量替换数组元素
数组中的元素定义完成后,可通过Arrays类的静态方法fill()来对数组中的元素进行分配,可以起到填充和替换的效果。
1.fill(int[] a,int value)
语法如下:
Arrays.fill (int [ ] a , int value)
a : 要进行元素分配的数组。
value : 要存储数组中所有的元素的值。
2.fill(int[] a ,int fromlndex ,int tolndex, int value)
语法如下:
Arrays.fill (int [ ] a , int fromIndex , int toIndex , int value )
value : 要使用指定值填充的第一个元素的索引(包括)。
toIndex : 要使用指定值填充的最后一个元素的索引(包括)
4.4.3 复制数组
在 Java 中实现数组复制分别有以下 4 种方法:
Arrays 类的 copyOf() 方法
Arrays 类的 copyOfRange() 方法
System 类的 arraycopy() 方法
Object 类的 clone() 方法
1.copyOf()方法
Arrays.copyOf(arr,int newlength)
数据类型[ ] 新数组名 = Arrays.copyOf(旧数组名,新数组长度)
2.copyOfRange()方法
Arrays.copyOfRange ( arr , int formIndex , int toIndex , int toIndex)
数据类型[]新数组名 = Arrays.copyOfRange(旧数组名,数组前序号,数组后序号);
import java.util.Arrays;
public class Test19{
public static void main(String[] args) {
// 定义长度为 5 的数组
int scores[] = new int[]{57,81,68,75,91};
// 输出原数组
System.out.println("原数组内容如下:");
// 循环遍历原数组
for(int i=0;i<scores.length;i++) {
// 将数组元素输出
System.out.print(scores[i]+"\t");
}
// 定义一个新的数组,将 scores 数组中的 5 个元素复制过来
// 同时留 3 个内存空间供以后开发使用
int[] newScores = (int[])Arrays.copyOf(scores,8);
System.out.println("\n复制的新数组内容如下:");
// 循环遍历复制后的新数组
for(int j=0;j<newScores.length;j++) {
// 将新数组的元素输出
System.out.print(newScores[j]+"\t");
}
}
}
使用 CopyOfRange() 方法对数组进行复制
srcArray 表示原数组。
startIndex 表示开始复制的起始索引,目标数组中将包含起始索引对应的元素,另外,startIndex 必须在 0 到 srcArray.length 之间。
endIndex 表示终止索引,目标数组中将不包含终止索引对应的元素,endIndex 必须大于等于 startIndex,可以大于 srcArray.length,如果大于 srcArray.length,则目标数组中使用默认值填充。
注意:目标数组如果已经存在,将会被重构。
4.5 数组的排序
程序常用的排序方法有冒泡排序、选择排序等。
4.5.1 算法:冒泡排序
冒泡排序(Bubble Sort)是常用的数组排序算法之一,它以简洁的思想与实现方法而备受青睐,也是广大学习者最先接触的一种排序算法。
冒泡排序的基本思想是:对比相邻的元素值,如果满足条件就交换元素值,把较小的元素值移动到数组前面,把大的元素值移动到数组后面(也就是交换两个元素的位置),这样数组元素就像气泡一样从底部上升到顶部。
冒泡排序的算法比较简单,排序的结果稳定,但时间效率不太高。Java 中的冒泡排序在双层循环中实现,其中外层循环控制排序轮数,总循环次数为要排序数组的长度减 1。而内层循环主要用于对比相邻元素的大小,以确定是否交换位置,对比和交换次数依排序轮数而减少。
4.5.2算法:选择排序
直接选择排序方法属于选择排序的一种,它的排序速度要比冒泡排序快一些,也是常用的排序算法。 使用选择排序法也可以对上述数组中的元素进行排序,但是它与冒泡排序不同。选择排序是指每一趟从待排序的数据元素中选出最大(或最小)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。
4.5.3 Arrays.Sort()方法
通过Arrays类的静态sort()方法可实现对数组的排序。sort()方法提供了多种使用方法,可对任意类型数组进行升序排序。
语法如下:
Arrays.sort (object)
object : 被排序的数组
4.6 小结
创建数组,给数组赋值以及读取数组中元素的值。