新手初学Java数组
作者:Prpr君
什么是数组
- 数组是相同类型数据的有序集合
- 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。
- 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们
数组的声明创建
- 首先必须声明数组变量,才能在程序中使用数组。下面是声明数组变量的语法:
dataType[] array;//例: int[] nums; 推荐使用这种写法 或者 dataType array[];//例: int nums[];
使用new来创建数组的语法:
dataType[] array = new dataType[arraySize]//例 int[] nums = new int[10];
数组的元素是通过索引访问的,数组索引从0开始。
获取数组的长度:array.length
练习:用循环给数组赋值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); }
内存分析:
结合以上练习和这张简单的内存分析思维导图来简单分析一下数组是如何生成在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类
- 数组的工具类
java.util.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+"\t"); } 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("行"+"\t"+"列"+"\t"+"值"); for (int i = 0; i < array2.length; i++) { System.out.println(array2[i][0]+"\t" +array2[i][1]+"\t" +array2[i][2]+"\t"); } 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+"\t"); } System.out.println(); } }
结果:
总结
本篇文章就到这里了,希望能够帮助到你,也希望您能够多多关注脚本之家的更多内容!