什么是数组
- 数组是相同类型数据的有序集合
- 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。
- 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们
数组的声明创建
- 首先必须声明数组变量,才能在程序中使用数组。下面是声明数组变量的语法:
dataType[] array;//例: int[] nums; 推荐使用这种写法 或者 dataType array[];//例: int nums[];
使用new来创建数组的语法:
dataType[] array = new dataType[arraySize]//例 int[] nums = new int[10];
数组的元素是通过索引访问的,数组索引从0开始。
获取数组的长度:
练习:用循环给数组赋值1到10,并输出数组的总和
public static void main(String[] args) { //创建一个数组 int[] array = new int[10]; //sum为总和 int sum = 0; //循环给数组赋值 for (int i = 1;i<=array.length;i++){ array[i-1] = i; } //循环遍历数组,把每位加到sum计算总和 for (int j = 0;j<array.length;j++){ sum = sum + array[j]; } System.out.println("数组总和为:"+sum); }
内存分析:
结合以上练习和这张简单的内存分析思维导图来简0基础学java数组单分析一下数组是如何生成在java内存的?
三种初始化状态
- 静态初始化
int[] a = {1,2,3}; Man[] mans = {new Man(1,1)}//Man是类名
- 动态初始化
int[] a = new int[2]; a[0] = 1; a[1] = 2;
数组的默认初始化
动态初始化包含了默认初始化。数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。
int[] a = new int[2];//可以理解为一但通过new实例化了,数组的每个元素也同样的被实例化位默认值存在堆的空间里
数组的四个基本特点
- 其长度是确定的。数组一旦被创建,它的大小就是不可以改变的。
- 其元素必须是相同类型,不允许出现混合类型。
- 数组中的元素可以是任何数据类型,包括基本类型和引用类型。
- 数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的。
数组的使用
For-Each循环
public static void main(String[] args) { int[] arrays = {1,3,5,7,9}; //JDK1.5以上可以使用,但是没有下标 for (int array : arrays) { System.out.println(array); } }
数组作方法入参
public static void main(String[] args) { int[] arrays = {2,4,6,8,10}; printArray(reverse(arrays));//输出10 8 6 4 2 } //打印数组元素 public static void printArray(int[] arrays){ for(int i = 0; i < arrays.length; i++){ System.out.print(arrays[i]+" "); } }
数组作返回值
public static void main(String[] args) { int[] arrays = {2,4,6,8,10}; //使用for-each遍历出反转后的数组 for(int array : reverse(arrays)){ System.out.print(array+" "); } } //反转数组,从数组最后一个元素到第一个元素 public static int[] reverse(int[] arrays){ int[] result = new int[arrays.length]; for (int i = 0,j=arrays.length-1; i < arrays.length; i++,j--) { result[j] = arrays[i]; } return result; }
多维数组
多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组。
二维数组
int a[][] = new int[3][2]//可以看作一个3行2列的数组来理解
例:创建并打印二维数组的所有元素
public static void main(String[] args) { int[][] arrays = {{1,2},{3,4},{5,6}}; for (int i = 0; i <arrays.length ; i++) { for (int j = 0;j<arrays[i].length;j++){ System.out.print(arrays[i][j]+" "); } System.out.println(); } }
Arrays类
- 数组的工具类
- 由于数组对象本身并没有什么方法可以供我们调用,但API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作。
- Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而"不用"使用对象来调用(注意:是"不用”而不是"不能")
常用功能:
返回指定数组的内容的字符串表示形式,通过toString方法。
public static void main(String[] args) { int[] arrays = {9,5,8,7,100,365,277,25,64}; System.out.println(Arrays.toString(arrays)); }
将指定的int值分配给指定的int数组的每个元素:通过fill方法。
public static void main(String[] args) { int[] arrays = {9,5,8,7,100,365,277,25,64}; Arrays.fill(arrays,0);//给数组里面所有元素替换为0 System.out.println(Arrays.toString(arrays)); //输出[0, 0, 0, 0, 0, 0, 0, 0, 0] int[] arr = {9,5,8,7,100,365,277,25,64}; // a - 要填充的数组 // fromIndex - 要用指定值填充的第一个元素(包括)的索引 // toIndex - 要用指定值填充的最后一个元素(排除)的索引 // val - 要存储在数组的所有元素中的值 Arrays.fill(arr,0,5,9);//给数组里面所有下标范围替换为9 System.out.println(Arrays.toString(arr)); }
对数组排序:通过sort方法,按升序。
public static void main(String[] args) { int[] arrays = {9,5,8,7,100,365,277,25,64}; Arrays.sort(arrays);//数组进行排序:升序 System.out.println(Arrays.toString(arrays)); //输出[5, 7, 8, 9, 25, 64, 100, 277, 365] }
比较数组:通过equals方法比较数组中元素值是否相等。
public static void main(String[] args) { int[] arrays = {9,5,8,7,100,365,277,25,64}; int[] arrays2 = {9,5,8,7,100,365,277,25,64}; boolean flag = Arrays.equals(arrays, arrays2); System.out.println("arrays和arrays2中的元素比较结果:"+flag); }
冒泡排序
冒泡排序算法的运作:
- 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。比较完最后一对则最后的元素会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
代码示例:
public static void main(String[] args) { int[] arrays = {9,5,8,7,100,365,277,25,64}; sort(arrays); } //冒泡排序:比较相邻的元素。如果第一个比第二个大,就交换他们两个的值 public static void sort(int array[]){ //temp是临时变量,用于比较的值进行交换 int temp = 0; for (int i = 0; i < array.length-1; i++) { for (int j = 0; j < array.length-1-i; j++) { if(array[j]>array[j+1]){ temp = array[j]; array[j] = array[j+1]; array[j+1] = temp; } } } System.out.println(Arrays.toString(array)); }
以上代码通过可以通过断点Debug发现,排序过程中,执行完最后的排序后,虽然数据已全部排序完备,但程序无法判断是否完成排序
为了解决这一不足,可设置一个标志位flag来进行优化,将其初始值设置为false,表示被排序的表是一个无序的表,每一次排序开始前设置flag值为false,在进行数据交换时,修改flag为非true。在新一轮排序开始时,检查此标志,若此标志为false,表示上一次没有做过交换数据,则结束排序;否则进行排序;
例:
public static void main(String[] args) { int[] arrays = {9,5,8,7,100,365,277,25,64}; sort(arrays); } public static void sort(int array[]){ //temp是临时变量,用于比较的值进行交换 int temp = 0; for (int i = 0; i < array.length-1; i++) { boolean flag = false; for (int j = 0; j < array.length-1-i; j++) { if(array[j]>array[j+1]){ temp = array[j]; array[j] = array[j+1]; array[j+1] = temp; flag = true; } } if(flag==false){ break; } } System.out.println(Arrays.toString(array)); }
稀疏数组
- 当一个数组中大部分元素为0,或者为同一值的数组时,可以使用稀疏数组来保存该数组。
- 稀疏数组的处理方式是:
- 记录数组一共有几行几列,有多少个不同值
- 把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模
- 如下图:左边是原始数组,右边是稀疏数组
例:一个有11行11列的五子棋盘,下了黑子和白字和没下棋子的地方我们可以用不同数字表示
(0:无)(1:黑)(2:白)
因为该二维数组的很多值是默认值0,因此记录了很多没有意义的数据。我们可以用稀疏数组来优化压缩
public static void main(String[] args) { //1.创建一个二维数组array1 有11行11列 (0:无 1:黑 2:白) int[][] array1 = new int[11][11]; //根据示例图表示,1在第二行第三列,2在第三行第四列 array1[1][2] = 1; array1[2][3] = 2; //输出原始数组 System.out.println("输出原始数组"); for(int[] ints : array1){ for (int anInt : ints){ System.out.print(anInt+" "); } System.out.println(); } System.out.println("=========================================="); //2.获取有效值的个数 int sum = 0;//sum拿来记录有效个数 //11为二维数组的行数 for (int i = 0; i < 11; i++) { //11为二维数组的列数 for (int j = 0; j <11 ; j++) { //如果几行几列的值不是0,则有效值个数+1 if(array1[i][j]!=0){ sum++; } } } System.out.println("有效值的个数:"+sum); //3.创建一个代表稀疏数组的数组array2 //sum+1中的+1是第一行要存放总共几行几列几个有效值的数据,3列是固定存放行、列、值 int[][] array2 = new int[sum+1][3]; array2[0][0] = 11;//总共多少行 array2[0][1] = 11;//总共多少列 array2[0][2] = sum;//有效值个数 //4.遍历二维数组,将非0的值存放在稀疏数组中 int count = 0;//记录行数 for (int i = 0; i < array1.length ; i++) { for (int j = 0; j < array1[i].length; j++) { if (array1[i][j]!=0){ count++;//查找到一个有效值就+1行记录在稀疏数组array2中 array2[count][0] = i;//横坐标 array2[count][1] = j;//纵坐标 array2[count][2] = array1[i][j];//值 } } } System.out.println("输出稀疏数组"); System.out.println("行"+" "+"列"+" "+"值"); for (int i = 0; i < array2.length; i++) { System.out.println(array2[i][0]+" " +array2[i][1]+" " +array2[i][2]+" "); } System.out.println("=========================================="); //5.把稀疏数组array2还原为原始数组array3 //稀疏数组中array2[0][0]和[0][1]固定存放是总共几行几列,array2是11行11列 int[][] array3 = new int[array2[0][0]][array2[0][1]]; //给其中的元素还原它的值,注意i要从1开始,因为array2[0]行存取的是几行几列 for (int i = 1; i < array2.length; i++) { //0是int数组中的默认值,所以只需要在有效值的位置还原 array3[array2[i][0]][array2[i][1]] = array2[i][2]; } //打印array3 System.out.println("输出还原数组"); for(int[] ints : array3){ for (int anInt : ints){ System.out.print(anInt+" "); } System.out.println(); } }
结果:
总结
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/h6javajc/24656.html