数组
一维数组
数组
-
相同数据类型
-
一定次序排列
-
一组变量的集合体
-
引用数据数据类型
数组元素
-
构成数组中的每一个数据计算数组元素
数组下标
-
下标就是数组元素的个数在数组中的位置,下标一般为整数,从0开始,也叫数组索引。
数组大小
-
数组中元素的个数叫做数组的大小,也就是数组的长度。
数组的步骤
定义数组
-
数据类型 数组名[];
-
数据类型[] 数组名;
为数组元素分配内存
数组明 = new 数据类型[数组长度]
scores = new int[5]
代码解析: (1)[5]表示数组的长度为 5,即 scores 数组包含 5 个元素。 (2) new 在Java 中就是分配内存的意思,也就是程序向JVM 申请连续的、可以存放5个int 类型变量的内存空间。new 申请的内存被分配在堆中,至于申请的内存空间的地址编号则是由JVM 决定的,开发人员无需关心,本例中使用 0xAA01~0xAA05 表示为数组元素分配的内存空间。 (3)等号“=”表示将 new 申请的内存空间的首地址赋值给数组 scores,数组 scores的值变成了 0xAA01,即 scores 变量指向到 new 分内的内存空间中,可以理解为数组名 scores代表了申请的5个元素。 (4)向数组中存储数据时,数据是存储在数组元素的内存空间中,即数据存储在scores[0]、scores[1]、scores[2]、scores[3]、scores[4]中。 (5)数组是什么类型,数组元素就是什么类型。由于 scores 数组是 int 的,因此scores数组的元素也是 int 类型的,由于 int 类型的变量默认值是0,因此每个 scores 数组元素的默认值是0。 (6)int 类型的数组是引用类型,int 数组的元素是基本类型
数组元素初始化
-
初始化就是第一次赋值的意思
数组元素类型 默认初始值 byte short int long 0 float double 0.0 char \u0000 boolean false 引用数据类型 null
使用数组
重要提示 (1)Java 将数据类型分为两大类,一类是基本数据类型,一类是引用数据类型 (2)它们的区别是基本数据类型的变量中存储的是真实的数据,而引用类型的变量中存储的是内存地址编号。如上例中数组名 scores就是引用类型,其值0xFF16是内存地址编号。scores[0]是基本数据类型,其值是真实数据 12。
增强数组
使用增强for循环遍历数组 JDK15及其之后的版本中提供了增强 for 循环语句,实现了terable'接口的类都可以使用增强for循环进行元素的迭代。增强for 循环的语法规则如下: for(元素类型 变量名:要迭代的对象) 语法解析: (1)元素类型是指数组或集合中的元素的类型 (2)变量名在循环时用来保存每个元素的值 (3)冒号后面是要遍历的数组或集合的名称 这里定义class类省略: int[] scores = new int {12,34,56,78,99,11} for(int s : scores){ System.out.println(s); } 结果:依次输出数组中从scores[0]到scores[scores.lenght-1]
数组元素排序
排序算法有多种,常用的排序算法有冒泡排序、插入排序、选择排序、快速排序、堆排序、归并排序、希尔排序、二叉树排序、计数排序等。
冒泡排序
import java.util.Arrays; public class BubbleSort { public static void main(String[] args) { int arr[] = new int[]{1,3,2,5,4,8,15,22,11,34,3}; for (int i = 0; i < arr.length-1; i++) {//比较次数 for (int j = 0; j < arr.length-1-i; j++) {//下标比较 if (arr[j]>arr[j+1]){//比较下标对应的值 int temp = arr[j];// arr[j]= arr[j+1]; arr[j+1]= temp; } } System.out.printf("第%d次比较结果为%s\n",i,Arrays.toString(arr)); } System.out.println("最终结果"+Arrays.toString(arr)); } }
选择排序
import java.util.Arrays; public class SelectionSort {//选择排序 public static void main(String[] args) { int arr[] = new int[]{1,3,5,2,6,1}; for (int i = 0; i < arr.length-1; i++) {//比较的次数 int min = i;//默认下标0就是最小值进行判断 for (int j = i+1; j < arr.length ; j++) {//从下标1开始和下标0进行判断,arr.length-1就无法判断最后一个值 if (arr[j]<arr[min])//如果判断的下标比默认0的下标小那就把min重新定义为比默认下标0还要小的下标j的位置 min = j;//把下标j给下标min ,此时下标min就是最小值 }//一轮循环比较完开始互换位置将最小的放在下标0的位置 int temp = arr[i];//从小到大排序交换 arr[i] = arr[min]; arr[min] = temp; System.out.printf("第%d次结果为%s\n",i,Arrays.toString(arr)); } System.out.println("最终结果为"+Arrays.toString(arr)); } }
插入排序
import java.util.Arrays; public class InsertionSorting { public static void main(String[] args) { int arr[] = new int[]{2,1,3,6,4,8,2}; for (int i = 1; i < arr.length; i++) {//以为需要当前值与前一位比较所以从下标1开始循环 int current = arr[i];// 当前值 int preindex = i-1;///当前值的前一位 while ( preindex >= 0 && arr[preindex] > current ) { //当前值小于前一个值是 arr[preindex + 1] = arr[preindex];//把前一个值往后往一位 preindex--;//判断与前一个值的大小,不满足继续下面操作,注意此时preindex已经发生减一操作所以之后赋值需要加一否则会出现数组范围异常 } System.out.printf("第%d次结果为%s\n",i,Arrays.toString(arr)); arr[preindex+1] = current;//把当前值放在当前值的前一位,如果取消减一则会提示超出数组范围 } System.out.println(Arrays.toString(arr)); } }
多维数组
在 Java 中,可以使用多维数组来存储多个数据值,以便更好地组织和访问这些数据Java 中的多维数组是一种数组的数组,即一个数组的元素也是一个数组。Java 中的多维数组可以包含任意数量的维度。在处理多维数组时,需要注意数组下标的范围,以避免数组越界异常。同时,还可以使用循环嵌套来遍历多维数组中的所有元素。
二维数组
Java 中定义和操作多维数组的语法与一维数组类似。在实际应用中,三维及其以上的数组使用很少,主要使用二维数组。使用二维数组同一维数组的步骤, (1)定义数组(2)为数组元素分配内存(3)数组元素初始化(4)使用数组。下面主要以二维数组为例进行讲解。(1)定义二维组
-
定义二维数组的语法规则如下: 数据类型 数组名 ;
-
数据类型 数组名 ;
Java 虽然支持多维数组,但是从内存分配原理的角度看,Java 只支持一维数组。或者说表面上是多维数组,实质上都是一维数组。 二维数组实际上是一个一维数组,这个一维数组的每一个元素又是一个一维数组。
Arrays类
JDK 中提供了一个专门用于操作数组的工具类,即Arrays 类,位于java.util 包中。该类提供了一些列方法来操作数组,如排序、复制、比较、填充等,用户直接调用这些方法即可,不需要自己编码实现,降低了开发难度。
方法 | 返回类型 | 说明 |
---|---|---|
equals(array1,array2) | boolean | 比较两个数组是否相等 |
sort(array) | void | 对数组 array的元素进行排序 |
toString(array) S | String | 将一个数组 array 转换成一个字符串 |
fill(array,val) | void | 把数组array 的所有元素都赋值成val |
copyOf(arraylength) | 与array 数据类型一致 | 把数组 array 复制成一个长度为length 的新数组 |
binarySearch(arrayval) | int | 查询元素值 val 在数组array 中的下标 |
compare(array1,array2) | int | 按字典顺序比较数组,前面的数组大,返回大于0的值,反之返回小于0的值 |
copyOfRange(arr,start,end) | 与array数据类型一致 | 将指定数组的指定范围复制到新数组中。 |
fill(arr,start,end, val) | void | 将指定的值分配给指定数组的指定范围的每个元素。 |
mismatch(arrayl,array2 | int | 查找并返回两个数组之间第一个不匹配的索引否则如果未找到不匹配,则返回 -1。 |
mismatch(arrayl,start1end1,array2,start2,end2) | int | 查找并返回指定范围内两个数组之间第一个不匹配的相对索引,否则如果未找到不匹配,则返回-1 |
常见问题
-
下标越界异常
分析下面的代码,运行时会出现什么异常?
public class Main { public static void main(String[] args ){ int[] scores =new int[ ](67,78,65,88,79); } }
System.outprintln"第5个学生的成绩是"+scores[5]); 图4-15示例13代码运行程序,显示如图4-16 所示的异常。 Exception in thread "main" java,lang.ArrayIndexQur0fBoundsException Create breakpoint :Index 5 out of bounds for length 5 at chapo4.section10,Main,main(Main.javar8)
系统提示运行该程序时发生了ArraylndexOutOfBoundsException 异常,这个异常表示数组的下标越界了,数组下标的界限是介于 0到数组长度减一范围内的整数,数组下标超出这个范围的值就会发生下标越界异常。 本例中 scores 数组中有 5 个元素,下标界限介于0到4之间,而输出下标为5的元素已经越界,因此JVM 抛出下标越界异常。
-
没有分配内间
- 分析下面的代码,运行时会出现什么异常? public class Main { public static void main(String[] args) { int[] scores = null; System,out.println("第1个学生的成绩是”+ scores[0]); } }
系统提示运行该程序时发生了 NullPointerException 异常,这个异常表示空指针异常。这个程序只为数组名称在栈中分配了内存,但是并没有在堆中为数组元素分配内存。当输出scores[0]时,表示输出数组 scores 指向内存空间中的第一个元素,但是数组 scores 并没有指向任何内存空间,因此 scores 是空指向(即 scores 的值是 null),因此JVM 抛出空指针异常,如图4.8 所示。解决的办法是为数组元素分配内存,并让数组 scores 指向到数组元素代码修改为 int[]scores=new int[5] 即可。
-
语法错误
一些常见的语法错误。
public static void main(String[] args) { //等号左边的中括号中不允许与长度,应改为int array1[]=newint[]{1,2,3}; int array1[ 3]=new int[](1,2,3); //直接为数组元素初始化时不允许指定数组长度,应改为int array2=new int[](1,2,3); int array2 = new int[3] {1,2,3}; //直接初始化数组元素的代码必须写在一行,应改为int array3[]=new int[]{1,2,3]; int array3[]; array3 = {1,2,3}