黑马程序员——JAVA基础之数组

------- android培训java培训、期待与您交流!--------

数组的基本概念

数组是一种存放数据的 容器
数组的数据数据类型都相同
数组具有一个固定的长度
l 数组中的数据都有一个唯一的编号叫做数组元素 索引 或数组元素 下标
数组的索引从 0 开始
访问数组中的元素使用 索引 来访问
创建数组的内存空间使用 new 关键字实现、

数组是一种简单的复合数据类型。它是存放具有相同数据类型的数值的数据结构,它的每一个元素都具有同一个类型,先后顺序也是固定的,数组一旦创建之后,大小就固定了,不再发生变化,它的数据类型既可以是简单类型,也可以是类,数组通常分为一维数组,二维数组和多维,但是使用比较多的还是一维数组和二维数组。

一维数组

一维数组可以存放成千上万个数据,它们是一组相关的存储单元,这些存储单元在逻辑上被看作是相互独立的若元素,它们具有相同的名字和数据类型,数组中的某个特定的元素有它的下标决定,只有一个下标的数组称为一维数组。声明一个一维数组的形式如下:

数据类型   数组名[ ]或者数据类型   [ ]  数组名

格式 1
数据类型 [ ]  数组名 ;
int [ ]   arr double[ ]  arr1;
boolean  arr2  [ ]  long  [ ] arr3
 
格式 2
数据类型 [ ]  数组名 new  数据类型 [ 数组长度 ];
int [ ]  arr = new int [4];
double  [ ] arr1 = new double[5];
 
格式 3
数据类型 [ ]  数组名 = new  数据类型 []{ 数组元素列表 };
数组元素列表包含数组中所有元素,中间用 , 分割
int [ ]  arr = new int [ ]{1,3,5,7,9};
long[ ]  arr1 = new long [ ] {2,4,6L,8,10L};
 
格式 4
数据类型 [ ]  数组名 = { 数组元素列表 };
int []  arr = {1,3,5,7,9};  不能分开赋值
 
这里的数据类型就是元所拥有的类型,常见的类型有整型、浮点型和字符型,数组名是用户自己定义的合法的标识符,用来统一这组相同数据类型的元素名称,其命名规范和变量相同,[ ]表示这是一个数组,数组一旦被定义,它的数据类型和数组名就不可更改。以上声明数组的语法格式都对,但是建议大家采用第一种例如:int [ ]  arrayName;就表示为int类型的一维数组,这样可以增加代码的可读性。
 
数组初始化
由于数组数组不过是一种特殊的类,Java中在数组声明时并不为数组分配空间,因此在声明的[ ]中不能指出数组中元素的个数即数组的长度,所以声明之后并不能立即使用,必须经过初始化并分配存储空间后,才能访问数组元素,为数组分配存储空间有两种方式:初始化和使用关键字new。
数组的初始化指的是在声明数组的同时为其元素赋初值,它的初始化格式如下:
数据类型  数组名 [ ] = {值1,值2,.....,值n};"{ }"中是初始化表,在声明时,并不需要将数组元素的个数列出,编译器根据所给出的初值个数来判断数组的长度,为这个数组分配足够的内存空间,并在这些空间中依次填入这些值,例如:
int  array[ ] = {0,1,2,3,4,5,6,8,9};
double day[ ] = {10.2,45.9,65.0,55.4};
在上面的语句中声明了一个整型数组array,虽然没有特别指明数组的长度,但由于大括号里的初值有9个,编译器会按从0~8的顺序将各元素进行存放,arr[0]为0,arr[1]为1,....,arr[8]为9,java中任何一个长度为n的数组,它的下标总是0,最后一个元素的下标总是n-1。
使用关键字new
通过使用new运算符可以为数组分配空间和指定初值,它的一般形式是:
数据类型  数组名 [ ];
数组名 = new  数组类型 [数组长度];  或将声明与创建写在一起:
数据类型  数组名[ ]  = new 数据类型  [数组长度];
其中数据类型和数组名与声明时的相同,数组声明后,接下来便是要配置数组所需的内存,其中"数组长度"是告诉编译器,所声明的数组要存放多少个元素,而"new"则是命令编译器根据括号里的数据个数,在内存中开辟一块内存空间供该数组使用。例如:
int a[ ];
a = new [5];
double [ ]  b = new double [10];
一旦数组初始化或用new为数组分配了存储空间以后,该数组的长度即被固定下来,不能在进行改变,除非在新建一个数组,重新分配存储空间。
!注意对同一个数组再次动态分配空间时,即用new运算符创建,若该数组的存储空间没有进行另外的存储,那么该数组的数据将会丢失。例如:
int array [ ] = {11,12,13,14,15};   array = new int [10];在这里通过new运算符为array数组重新分配空间,那么它原来的11,12,13,14,15将丢失。
 
引用
要引用一个数组,其实使用的是这个数组中的元素,想要使用数组里的元素,可以利用索引来完成,Java中的数组索引标号由0开始到数组长度-1为止数组元素使用形式:
数组名[下标]
[ ] 中的下标是介于[0,数组长度-1]之间的整型数,也可以是byte、short、char等类型,但是不允许为long型,当然下标也可以是合法的表达式。
如果要直接访问某数组中的最后一个元素,这时就需要用到数组的一个属性:length,它是一个特殊的属性,表示数组共有多少个元素,也是数组的长度,用户程序无法直接改变这个值,它的具体用法是:数组名.length,来看一个一维数组的使用方法的程序:
class  ArrayClass
{
	public static void main(String[] args) 
	{
		int i;
		int [] arr = new int [10];//声明数组并赋值开辟空间
		System.out.println("数组长度是: "+arr.length);//输出数组长度
		for (i=0;i<10;i++)//输出数组的元素内容。
		{
			System.out.print("a["+i+"]="+arr[i])+",");
			if (i%2==1)//控制打印行数,每行打印2个元素
			{
				System.out.println();
			}
		}
	}
}
运行结果:数组长度是:10
a[0] =0;a[1]=0;
a[2] =0;a[3]=0;
a[4] =0;a[5]=0;
a[6] =0;a[7]=0;
a[8] =0;a[9]=0;


上述代码声明了一个整型数组arr并用new运算符为其分配空间,其元素个数为10,然后利用for循环输出数组内容。由于程序中没有赋具体值,所以数组元素指向了int的默认值0,因此输出为0。arr .ength代表数组的长度为10,也就说数组元素个数是10个。
 
二维数组的概念
二维数组可以看做是一种特殊的一维数组,即数组中的元素全部是一维数组
二维数组中保存的一维数组必须结构相同,即保存的数组存储的数据类型必须完全相同
二维数组的长度仅仅表明其中保存的一维数组的数量,并不能约束其中保存的一维数组的长度
 
二维定义格式:
声明有3种:
数据类型   数组名[ ] [ ] 或者数据类型 [ ] [ ]  数组名 或者数据类型[ ]  数组名[ ]   它可以是简单的数据类型,也可以是复合类型,和一维数组一样,两个“[ ]”中都必须是空的。二维数组的合法声明形式:
int a [ ] [ ];     
double  [ ] [ ] b;
myClass [ ]  c [ ];
初始化:
二维数组的初始化同一维数组一样,在声明数组的同时为数据元素赋初值:
二维数组声明的方式和一维数组类似,内存的分配也一样用new这个关键字。与一维数组不同的是,二维数组在分配内存时,必须告诉编译器二维数组的行与列的个数,“行的个数”是告诉编译器所声明的数组多少行(行指的是一维数组的个数);“列的个数”则是说明该数组有多少列(一个一维数组中有多少个元素);例如:
int a [ ] [ ] = new int [4] [6];  z这里创建了一个4行6列的整型二维数组a,它仍然由4个一维数组组成,每个一维数组的长度都是6。
格式 2
数据类型 [] [] 数组名 new  数据类型 [ 长度 ] [ 长度 ];
int [][] arr = new int [4][5];
double  [][] arr1 = new double[5][10];
 
格式 3
数据类型 [][]  数组名 = new  数据类型 [][]{{ 数组元素列表 1},{ 数组元素列表 2},……};
int [][] arr = new int [][]{{1,3},{7,9}};
long[][]arr1 = new long[][] {{2,4},{6L,8},{10L,12L}};
 
格式 4
数据类型 [][]  数组名 = {{ 数组元素列表 1}, { 数组元素列表 2},……};  不能分开赋值
int [][]  arr = {{1,3},{5,7}};
 
格式 5
数据类型 [][]  数组名 = new 数据类型 [ 长度 ][];
数组名 [ 索引 ] = new 数据类型 [ 长度 ];
先对二维数组外层数组的长度进行初始化,然后再对其中保存的数据即内层一维数组进行单独初始化
使用此格式可以创建出特殊的二维数组,即其中保存数据的一维数组长度均不相同
此格式更有利于对现实生活中的数据进行描述
 
 
!注意: 由于二维数组可以看作是一维数组的数组,所以数组的内存空间不一定是连续的,所以不要求二维数组中每一维的大小必须相同。
 

引用 :

Java是通过以下方式来引用二维数组的元素的,引用形式为;

数组名 [行号] [列号]      例如:

n = a[3][4];   表示要访问二维数组a的第4个一维数组中的第5个元素,如果要访问所以元素中的第一个应该这么些:n = a[0] [0];

如果要直接访问所以元素中的最后一个,要这么写:

r = a.length-1;

c1 =a[r].length-1;

k = a[r] [c1];

!注意:不管在多维数组中还是在一维数组中,下标都是从0开始到数组的长度-1为止

数组名.length     //取得数组的行号即一维数组的个数。

数组名[行的索引].length  //取得特定行元素的个数即指定的一维数组内的元素的个数。

下面是关于二维数组使用方法的程序:

class  ArrayClass_2
{
	public static void main(String[] args) 
	{
		int i,j,sum=0;
		int score[][]={{60,70,85,45},{89,78,86,66},{56,84,76,91}};//声明数组并设置初值

		for (i=0;i<score.length;i++ )
		{
			sum = 0;
			System.out.println("第"+(i+1)+"个人成绩为:");
			for (j=0;j<score[i].length ;j++)
			{
				System.out.println(score[i][j]+" ");//输出个人单科成绩
				sum+=score[i][j];//计算总成绩
			}
				System.out.println("总成绩为: "+sum);
		}
	}
}
运行结果:
第1个人的成绩为:60 70 85 45 总成绩为:260
第2个人的成绩为:89 78 86 66 总成绩为:319
第3个人的成绩为:56 84 76 91 总成绩为:307

上面这段程序利用整数变量i、j作为外层循环与内层循环控制变量及数组的下标,变量i控制行的个数,变量j控制一行中列的个数;而sum则用来存放所以数组元素的和,也就是总成绩。

数组最值

数组的最值可通过对数组中元素遍历,逐一比对,最终找到数组元素的最值
在进行数组最值的求解过程中,尽量避免使用固定值对数组元素进行比对,避免出现特殊值影响最终结果,可以改变数据保存的方式,使用索引作为保存的数据,完成求最值元素对应的下标的形式来避免上述问题
class ArrayDemo2{
	public static void main(String[] args){
		//数组求最值
		
		//思路
		//两两相比,留一个大的,再与下面的所有的
		//数重复两两相比,直到所有的数字全部比完
		
		int[] arr = {4,2,6,8,11,3,9};
		int max = 0;
		//遍历数组,使用每一个元素与max相比
		//如果比较的值比max小,跳过
		//如果比较的值比max大,将max改成比较的值
		//对数组循环完毕后,max就是最大值
		for(int i = 0;i<arr.length;i++){
			if(max<arr[i]){
				max = arr[i];
			}
		}
		System.out.println(max);
}	


 

数组排序

数组排序是数组的常用操作,数组排序方式有多种
冒泡排序法  交换排序法  选择排序法
插入排序法  基数排序法   希尔排序法
快速排序法   归并排序法   堆排序法

 

 选择排序

选择排序法是将原始数组空间分为两个部分,第一部分用于存放已经排序完成的数据,第二部分用于存在未完成排序的数据
排序过程中,每次从未完成排序

  的区域中找出最大/小值并将其放

  置到未完成排序区域的首位,然

  后改变两个区域的空间大小,并

  反复上述过程,直到未排序区只

  有一个数据

/*
数组的排序
选择排序法
选择排序法改良
*/
class SortDemo2{
	public static void main(String[] args){
		/*
		int[] arr = {4,26,51,38,3,45,69,87,70,92};
		
		for(int x = 0 ; x<arr.length -1 ;x++){
			//一轮
			//使用第一个作为参考值,然后与后面的每个元素进行比较,大就换
			for(int i = x+1 ;i<arr.length;i++){
				if(arr[x]>arr[i]){
					int temp = arr[x];
					arr[x] = arr[i];
					arr[i] = temp;
				}
			}
		}
		
		for(int i = 0;i<arr.length;i++){
			System.out.println(arr[i]);
		}
		*/
		int[] arr = {4,26,51,38,3,45,69,87,70,92};
		
		//一轮
		//设置0号为参考值
		for(int x = 0;x < arr.length-1;x++){
			int temp = x;
			//使用参考值与1号比,谁大谁做参考值
			for(int i = x+1; i < arr.length ;i++){
				if(arr[temp]<arr[i]){
					temp = i;
				}	
			}
			//交换
			//0位置与temp位置交换
			int temps = arr[x];
			arr[x] = arr[temp];
			arr[temp] = temps;
		}
		
		for(int i = 0;i<arr.length;i++){
			System.out.println(arr[i]);
		}
		
		
	}
}


 

冒泡排序

冒泡排序法是较为常用的排序方法,日常生活中大多数的排序方案均为冒泡排序法
排序过程中,使用第一个元素与第二个元素

  进行比较,并将其较大/小的放在后面,然后

  使用第二个与第三个元素进行比较,重复上

  述操作,当数组遍历一轮时,最大/小的元素

  将置于数组末端;第二轮,改变遍历数组范

  围,从第一个元素到倒数第二个元素,对其

  进行上述操作;第三轮对第一个元素到倒数

  第三个元素进行上述操作,如此反复,最终

  对数组实现排序

class SortDemo{//冒泡排序法
	public static void main(String[] args){
		
		int[] arr = {4,2,6,1,8,3,5,9,7,0};
		//找出最大的,把最大的放到队尾
		for(int i = 1 ;i<= arr.length - 1;i++){
			for(int j = 0;j<arr.length - i;j++){
				//比较两个相邻的数据,如果前面的大,交换位置
				if(	arr[j] > arr[j+1]){
					//数据交换
					int temp = arr[j];
					arr[j] = arr[j+1];
					arr[j+1] = temp;
				}
			}
		}
		for(int i = 0;i<arr.length;i++){
			System.out.println(arr[i]);
		}
	}
}		


减少排序过程中数据移动次数

排序过程中需要进行大量的元素位置对调的操作,这一操作将开销大量的运算时间,通过添加额外的数据存储区域,可以减少数据移动操作次数,此操作思想与求最值操作过程中使用的额外变量具有相同的功效

数组元素查找

数组中元素众多,最快速度的查找出需要的数据成为数组操作中的一个重要操作,常用查找方式如下
二分法查找  索引查找法  哈希查找法
二分法查找
二分法查找又名折半查找法,首先要保障要查询的数据是有序的,然后与数据总量一半位置处的数据进行比对,以升序排列为例,如果比对的结果发现查找数据比比对数据大,则在后半段再次重复上述操作,直到找到最终的数据。如果原始数据中不包含要查找的数据,数据查找将失败,通常返回一个固定的值 -1 作为查找失败的结果。
/*
二分法查找

*/
class QueryDemo{
	public static void main(String[] args){
		//查找得到的一定是对应所在的位置
		int num = 9;
		int[] arr = {1,2,3,4,5,6,7,8,9};
		
		int min = 0;
		int max =	arr.length-1;
		
		while(min<max){
			//比对值对应的索引
			int mid = (min+max)/2;
			//使用你要查找的数据域要比对的索引上的数据进行比对
			if(num > arr[mid]){
				//min要移动到mid+1,max不动
				min = mid + 1;
			}else if(num < arr[mid]){
				//max要移动到mid-1,min不动
				max = mid - 1;
			}else{
				System.out.println(mid);
				break;
			}
		}	
	}
}


 

关于数组暂时总结出这些,欢迎各位批评指正! 

 

 

 

 ----------------- android培训java培训、期待与您交流!------------------

 详细请查看:http://edu.csdn.net

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值