Java基础——数组 - Go语言中文社区

Java基础——数组


Java基础——数组

数组是一个语言中的基本要素,它能够用来保存和管理多个变量。例如,如果要统计三个学生的成绩,可以手动的定义三个变量 a、b、c,如果要输出这三个变量的值,也可以写三个输出语句。但是,如果要管理一个年级所有学生的成绩,此时,可能有上百个学生。如果为每个学生都手动定义一个变量的话,则程序中会有上百个变量。并且,如果要 输出所有学生的成绩,就会有上百个输出语句。很显然,这样的代码是非常复杂和繁琐的。

因此,我们就需要有一个办法,能够比较方便的管理多个数据。在这种情况下,我们就应该用到数组。

一、数组的基本操作

数组:一次性定义多个同类型的变量。

数组空间在内存中必定是连续的。

1,创建数组

int []a 或int a[] 表示定义一个int类型的一维数组变量a

a=new int[3]; 表示分配了一个长度为3个int的内存空间

int[]a=new int[3]; 也可以两部写在一块,表示定义一个int类型的一维数组同时分配长度为3个int的内存空间

2,下标

定义一个数组,就是一次性定义多个同类型的变量。为数组分配完空间之后,就可以使用数组了。使用数组的时候,应当用下标来表示数组元素。例如,上面分配了长度为3个int 类型的变量,这3个int 变量分别可以用:a[0]、a[1]、a[2]来表示。

即如果分配了一个长度为 n 的数组,则数组的下标范围为 0~n-1。

a[0] = 10; //对数组元素进行赋值

a[1] = 20;

a[2] = 30;

3,遍历数组

遍历数组:按照一定顺序,把每个元素都访问一遍,不会遗漏,不会重复

  示例代码:

package p5;
public class TestArray{
	public static void main(String [] args){
		int[]a;//数组的定义 int []a; int a [];
		a=new int[3];//初始化变量a,为数组分配空间,定义数组的长度
		a[0]=1;
		a[1]=2;
		a[2]=3;//数组的赋值
		for(int i=0;i<3;i++){//遍历数组
		System.out.println(a[i]);
		}
	}
}


运行结果:

  

4,数组的初始化

数组元素在没有赋值的情况下可以使用,数组元素有特定的默认值

byte、short、int、long 这四种整数类型,默认值为 0 

  float 和 double 这两种小数类型,默认值为 0.0

boolean 默认值为 false

char 默认值也为 0

注意,char 类型的 0 不是指的字符‘0’,而是指的编码为 0。

对于对象类型的数组来说,默认值为 null。


显示初始化

第一种形式如下:

int[] a = {10, 20, 30};

特点是,只能在定义数组变量的同时使用。

第二种语法形式如下:

int[] a = new int[]{10, 20, 30};

注意,这种语法下,new 关键字后面的方括号中没有数字,也就是说,显式初始化时不能规定数组长度,数组长度由后面的元素个数决定。

package p5;
public class TestArray{
	public static void main(String [] args){
		int[]a;//数组的定义 int []a; int a [];
		a=new int[3];//初始化变量a,为数组分配空间,定义数组的长度
		a[0]=1;
		a[1]=2;
		a[2]=3;//数组的赋值
		/*
		int[]a={1,2,3};//数组的显示初始化,数组长度有括号内元素个数决定
		//int []a=new int [](1,2,3);
		//int []a=new int [3](1,2,3); error!!!
		*/
		for(int i=0;i<3;i++){//遍历数组
		System.out.println(a[i]);
		}
	}
}

二、数组在内存中的表示

Java 数组在内存中的表示情况。看下面两行代码

int[] a;

  a = new int[3];

我们结合代码,分析一下数组在内存中的表示。

第一行,定义了一个数组变量 a,此时没有分配连续的内存空间。

第二行,首先执行了 new int[3],这句代码分配了一个段连续的内存空间,总共能够放 入 3 个 int,因此是 12 个字节。这 12 个字节每个字节都有自己的一个内存地址,其中,12 个字节中的第一个字节,它的地址被称之为这块内存的“首地址”。假设首地址为 1a2b。第三步,执行完了 new int[3]之后,进行了赋值。究竟是把什么赋值给了变量 a 呢?注 意,赋值赋的是内存的首地址。也就是说,数组变量保存的是数组中的首地址 1a2b。如下图所示

 

三、二维数组

1,二维数组的基本操作

二维数组以及多维数组:数组的数组。

比如说,我们日常生活中的抽屉,我们可以认为抽屉就是用来存放多个物品的,因此抽屉就是一个物品的数组。而一个柜子中,可以存放多个抽屉,因此我们可以理解为,柜子就是抽屉组成的数组。因此,柜子就可以理解为是“数组的数组”,也就是:柜子的元素是抽屉,而抽屉本身又是一个数组。

Ⅰ,创建二维数组

int[][] a; 或者 int[] a[]; 或者 int a[][];

定义二维数组变量的时候,同样没有分配数组空间。

 

a = new int[3][4];

为二维数组分配内存空间,分配一个三行四列的二维数组

我们可以这 么来看:我们分配的这个二维数组就相当于一个柜子,这个柜子有三层,每层放一个抽屉。这个抽屉里面分成了四个格子,每个格子又能放一个元素。由于二维数组是“数组的 数组”,因此,二维数组的“行”,指的是这个二维数组中,包含几个元素。由于二维数组 的元素是一维数组,因此,“行”也就是二维数组中包含几个一维数组。而列,则指的是, 二维数组中的每一个一维数组,各自都包含几个元素。

 

a[0][2]

表示第 0 行第 2 列的元素


int [][]a={{1,2,3}{5,6,7}{8,9,10}{11,12,13}};

二维数组的显示初始化

Ⅱ,遍历二维数组

遍历二维数组时,要获得行和列两个数值。

首先,二 维数组同样有 a.length 这样的变量,而使用 a.length 获得的长度,是二维数组元素的个数, 也就是行的数目,也可以理解成:柜子里抽屉的个数。而列的数目,就相当于是每一个一 1a2b a … … 1a2b 7 维数组的长度,也可以理解为,是每一个抽屉的大小。对于第 i 个抽屉,我们可以使用 a[i].length 来获得它的长度。

  示例代码:

package p5;
public class TestArray2{
	public static void main(String [] args){
		//int [][]a=new int[4][3];//二维数组变量的定义,并为二维数组分配内存空间
		//分配一个三行四列的二维数组
		// int [][]a=new int [][3];//error!!!
		int [][]a={{1,2,3},{5,6,7},{8,9,10},{11,12,13}};//二维数组的显示初始化
		for(int i=0;i<a.length;i++){//遍历二维数组
			for(int j=0;j<a[i].length;j++){
				System.out.print(a[i][j]+" ");
			}
			System.out.println();
		}
	
	}
}


 

  运行结果:


 

 

 

 

 

2,二维数组的内存表示


 


对于 a 数组来说,它还是一个一维数组,这个一维数组的长度为 3,也就 是说,a 数组有三个元素。而 a[0],a[1],a[2]又各自记录了一个一维数组的地址。因此我们把 a 数组称为“一维数组的一维数组”,也就是二维数组。

3,不规则数组

除了普通的二维数组之外,Java 还支持不规则数组。举例来说,如果一个柜子有三个 抽屉,这个三个抽屉中并不一定每个抽屉都具有一样的大小,完全有可能第三个抽屉更 大,元素更多,而第一个抽屉相对就比较小。

int[][] a; //定义数组变量

a = new int[3][]; //先确定第一个维度,表明柜子里有三个抽屉 a = new int[][3]; //error!

a[0] = new int[3]; //上层的抽屉有三个元素

a[1] = new int[4]; //下一层有四个元素

a[2] = new int[5]; //最底层有五个元素

 

四,数组的常见算法

1,数组的扩容

首先,数组空间一旦分配完成之后,长度就不能改变了。因此,我们不能够直接在原 有数组的空间后面增加新的内存空间。我们可以采用以下方式,来增加数组的长度:

①、分配一个新的数组,新数组的长度比原有数组要大(比如长度是原有数组的两倍)

②、把原有数组中的数据,复制到新数组中。

 

package p5;
import java.util.Arrays;
public class TestArrayExpand{
	public static void main(String []args){
	int []a={1,2,3,4};//定义数组a,并显示初始化a
	int []b=new int[8];//定义数组b,并为b分配内存空间,
	a=expand(a);
	}
	public static int[] expand(int[]a){//扩充方法1
		int []b=new int[a.length*2];
		for(int i=0;i<a.length;i++){
			b[i]=a[i];
		
	}
	return b;
		
	}
	public static int []expand1(int []a){//扩充方法2
		int []b=new int [a.length*2];
		System.arraycopy(a,0,b,0,a.length);
		return b;
	}
	public static int []expand2(int []a){//扩充方法3
		
		return Arrays.copyOf(a,a.length*2);
	}
}

 

2,冒泡排序

在排序的过程中,相邻元素不停进行比 较和交换。在交换的过程中,大的元素沉向数组的末尾,小的元素走向数组的开头;这就好像在水里面:重的东西往下沉,而轻的东西往上浮起来。正因为这种排序方式很像水里 的气泡往上浮的过程,因此,这种排序方式被称为冒泡排序。

接下来,我们来写冒泡排序的代码。如果有五个元素,则需要进行 4 次循环,也就是 说,如果数组的长度是 a.length 的话,则需要进行 a.length-1 次循环。因此,外层循环如下:

for(int i = 0; i<a.length-1; i++){
		…
		}

内层循环稍有点复杂。我们让内层循环的循环变量为 j,则每次进行比较的时候,比较 的都是 a[j]和 a[j+1]这两个元素。那么 j的循环条件怎么写呢?

第 1 次循环,i 的值为 0,因为要排到最后一个,因此 j+1 最大值为 a.length,j 的最大值为 a.length-1; 

  第 2 次循环,i的值为 1,j+1 的最大值为 a.length-1,j的最大值为 a.length-2;

第 3 次循环,i的值为 2,j+1 的最大值为 a.length-2,j的最大值为 a.length-3;

由上面,我们可知,每次循环 j+1 的最大值,都是 a.length-i;而 j 的最大值,就是 a.length-i-1。 因此,内层循环条件如下:

for(int i = 0; i<a.length-1; i++){
	for(int j = 0; j<a.length–i-1; j++){
		比较 a[j]和 a[j+1], 如果 a[j]比 a[j+1]大,则交换两个元素的值 13
		}
	}

进一步细化,代码为 

for(int i = 0; i<a.length-1; i++){ 
		for(int j = 0; j<a.length–i-1; j++){ 
			if(a[j] > a[j+1]){ 
				则交换 a[j]和 a[j+1]的值 
			} 
		} 
	}

如何交换两个变量的值呢?假设有两个变量 a = 5;b=4;要交换两个 a 和 b 的值,应该怎么做呢?

如果直接执行 a = b 的话,则 a 的值 5 就会被 b 的值覆盖。这样,a 有了 b 的值,但是 b 却无法获得 a 变量原来的值了。因此,为了交换两个变量的值,需要第三个变量参与。

首先,定义一个新变量 t; 然后,把 a 的值赋值给 t:t = a;

接下来,把 b 的值赋值给 a: a=b。这样会覆盖 a 原有的值,但是没关系,a 原有的值 已经被保存在 t 变量中了。

再接下来,把在 t 变量中保存的原有的 a 变量的值,赋值给 b。

  示例代码:

package p5;
public class TestArraySort{
	public static void main(String[]args){
		int []data={5,4,2,1,3};//定义一个一维数组,并显示初始化数组
		int n=data.length;//定义变量n为数组长度,便于后面使用数组长度
		for(int i=1;i<n;i++){//冒泡排序必定是n-1次,i表示第几次冒泡排序
			for(int j=0;j<(n-i);j++){//归纳总结,从0开始data[j]与data[j+1]比较,比较n-i次
				if(data[j]>data[j+1]){
				int t=data[j];
				data[j]=data[j+1];
				data[j+1]=t;//data[j]与data[j+1]交换位置
				}
				
			}	
			
			
		}
		
		for(int i=0;i<data.length;i++){
			System.out.print(data[i]+" ");//遍历输出data[i]
		}
		System.out.println();//换行
		
	 	
	}
}
运行结果:


 

3,选择排序

选择排序是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。选择排序是不稳定的排序方法(比如序列[5, 5, 3]第一次就将第一个[5]与[3]交换,导致第一个5挪动到第二个5后面)

package p5;
public class TestArraySort{
	public static void main(String[]args){
		int []data={5,4,2,1,3};//定义一个一维数组,并显示初始化数组
		int n=data.length;//定义变量n为数组长度,便于后面使用数组长度
		for(int i=0;i<(n-1);i++){//选择排序
			for(int j=i+1;j<n;j++){
				if(data[i]>data[j]){
					int t=data[i];
					data[i]=data[j];
					data[j]=t;
				}
			}
			
		}
		
		for(int i=0;i<data.length;i++){
			System.out.print(data[i]+" ");//遍历输出data[i]
		}
		System.out.println();//换行
		
	 	
	}
}

 

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/zzj_csdn/article/details/77345470
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-04-19 13:11:58
  • 阅读 ( 709 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢