黑马程序员-数组

-----------android培训java培训、java学习型技术博客、期待与您交流! ------------


一、数组概念:

数组是同一种类型数据的集。.其实数组就是一个 容器
它的好处是可以从0开始编号,方便操作这些元素。

二、数组的格式:

格式1:
元素类型[] 数组名 = new 元素类型[元素个数或数组长度];
示例:int[] arr = new int[5];//创建数组实体的关键字
格式2:
元素类型[] 数组名 = new 元素类型[]{元素,元素,……};
int[] arr = new int[]{3,5,1,7};
int[] arr = {3,5,1,7};(不会在内存开辟空间)
静态初始化:初始化时由程序员显式指定每个数组元素的初始值,由系统决定数组长度。
动态初始化:初始化时程序员只指定数组长度,由系统为数组元素分配初始值。



三、数组在内存中分布情况图:

如:String [] arr = new String [5];


int[] arr = new int[5];//arr是引用类型变量,指向堆内存中的一个实体;

arr[0] = 15;//给零角标位置赋值

arr = null;//没有任何实体指向

栈内存特点:存储局部变量,在方法执行完会随方法弹栈.会自动释放空间

堆内存特点:存储的是数组和对象,凡是用new建立的实体都存在于堆中

1,每一个实体都有内存地址值

2,每一个实体都有默认初始化值

int--->0;  double--->0.0;  boolean--->false;  char----->'\u0000';

3,当实体不被使用时将被视为垃圾,java有一个垃圾回收机制,对垃圾进行回收,对堆内存进行释放。

四、为什么使用数组:


当我们定义一个变量时可以使用一个变量名表示,但是如果出现很多的变量我们分别起变量名代替表示存储就比较麻烦了,为了解决这样的问题我们采用数组的形式来进行存储,使用下标表示每个变量。
数组只有一个名称,即标识符
数组中每一个元素都能通过下标来访问
数组角标:从0开始
数组长度:变量名.length,数组的长度是固定的,因为它的底层是public和final修饰
数组最大角标值:length-1 数组长度固定,避免角标越界
数组动态初始化:int[] arr = new int[5];
数组静态初始化:int[] arr = {1,2,3,4};
数组定义的注意事项:
1,数组定义时,必须明确元素的类型。
2,数组定义时,必须明确元素的个数。
u什么时候使用数组?
当要操作的同种数据类型的变量较多时,需要将这些数据进行存储,这时就需要用的容器,而数组就是容器中的一种.

五、数组常见的错误:


1)int[] arr = new int[];//没有注明数组大小

2)int[] arr = new int[5];

   System.out.println(arr[5]);//数组下标越界

ArrayIndexOutOfBoundsException//访问到了数组中不存在的角标。但是编译可以通过。因为,new运行的时候,只是在运行的时候才建立数组,编译时只进行语法检查,编译只能检查出语法错误。new只有在运行的时候才在堆内存开辟一块内存空间,并分配0,1,2,3,4,这5个角标,换个角度说编译的时候就这个数组已经把堆内存的空间占用,如果不运行会造成空间的浪费

3)int[] arr;

    arr = {1,2,3,4};//创建数组并赋值的方式,必须在一条语句中完成。

4)int[] arr = null;//arr不指向任何实体

System.out.println(arr[0]);

NullPointerException//空指针异常


六、数组操作:


1、数组格式

数组格式:
会在内存开辟空间
 int [] arr = new arr[5];//下面五个数组就是
 int [] arr1 =new arr[]{20,5,42,1,5};//arr[]不要定义个数,避免不符合
 arr[0]=10; 
 arr[1]=2; 
 arr[2]=8; 
 arr[3]=19; 
 arr[4]=11; 
不会在内存开辟空间
 int [] arr2 ={45,5,44,1,15,6};


2、遍历

数组用逗号隔开打印在控制台上

class  Demo
{
	public static void main(String[] args) 
	{
		int [] arr= {12,15,11,5,4,8};
		printArray(arr);//打印数组
	}
		//定义功能,打印数组中的元素,用逗号隔开
	public static void printArray(int[] arr)
	{
		System.out.print("[");
		//数组中有一个属性获取数组的元素个数——length
		for (int x=0;x<arr.length ;x++ )
		{
			if (x<arr.length-1)
				System.out.print(arr[x]+",");
			else
				System.out.print(arr[x]+"]");			
		}
	}
}

3、获取最值

获取数组中的最大值。(最小值思路同理)
	思路:
	1,获取最值需要进行比较。每一次比较都会有一个较大的值。因为该值不确定。
	通过一个变量进行临储。
	2,让数组中的每一个元素都和这个变量中的值进行比较。
	如果大于了变量中的值,就用该该变量记录较大值。
	3,当所有的元素都比较完成,那么该变量中存储的就是数组中的最大值了。

	步骤:
	1,定义变量。初始化为数组中任意一个元素即可。
	2,通过循环语句对数组进行遍历。
	3,在变量过程中定义判断条件,如果遍历到的元素比变量中的元素大,就赋值给该变量;
	
	需要定义一个功能来完成。以便提高复用性。
	1,明确结果,数组中的最大元素 int。、
	2,未知内容:一个数组。int[]


代码:

//给定一个数组{10,5,44,15,16,20,1}
//获取数组中的最大值和最小值
class  Demo
{
	public static void main(String[] args) 
	{
		int [] arr ={10,5,44,15,16,20,1};//创建给定数组
		//获取最大值
		int max = arrayTest(arr);
		System.out.println(max);
		//获取最小值
		int min = arrayTest_1(arr);
		System.out.println(min);
	}
	public static int arrayTest(int[] arr)//创建方法获取最大值
	{
		int num=0;//定义第三方变量方法,初始化临时变量为0,其实就是初始化为任一个数组中的角标
		for (int x=0;x<arr.length ;x++ )
		{
			if (arr[x]>arr[num])
			{
					num=x;
			}
		}
		return arr[num];
	}
	public static int arrayTest_1(int [] arr)//获取数组中最小值
	{
		int min=arr[0];
		for (int y=0;y<arr.length ;y++ )
		{
			if (min>arr[y])
			{
				min=arr[y];
			}
		}
		return min;
	}
}


4、选择排序和冒泡排序


JAVA中在运用数组进行排序功能时,一般有四种方法:快速排序法、冒泡排序法、选择排序法、插入排序法。其中常见的是选择排序法和冒泡排序法。

选择排序原理:

1.将数组中每个元素与第一个元素比较,如果这个元素小于第一个元素,则交换这两个元素

2.循环第1条规则,找出最小元素,放于第1个位置

3.经过n-1轮比较完成排序

简单而言,每轮都找到最小的放到前面。例:{8 ,2 , 3 , 7 , 1}的排序过程如下所示:

数 组: arr={8 , 2 , 3 , 7, 1}

1: arr={1 | 8 , 3 , 7 , 2}

2: arr={1 , 2 | 8 , 7 , 3}

3: arr={1 , 2 , 3 | 8 , 7}

4: arr={1 , 2 , 3 , 7 | 8}

5: arr={1 , 2 , 3 , 7 | 8}

冒泡排序原理:

 1.比较相邻的元素,将小的放到前面。

 2.依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小 数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。至此第一趟结束,将最大的数放到了最后。

 3.在第二趟:仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再小于第2个数),将小数放前,大数放后,一直比较到倒数第二个数(倒数第一的位置上已经是最大的),第二趟结束,在倒数第二的位置上得到一个新的最大数(其实在整个数列中是第二大的数)。如此下去,重复以上过程,直至最终完成排序。

  由于在排序过程中总是小数往前放,大数往后放,相当于气泡往上升,所以称作冒泡排序。

  用二重循环实现,外循环变量设为x,内循环变量设为y。外循环重复5次,内循环依次重复4,3,2,1次。每次进行比较的两个元素都是与内循环y有关的,它们可以 分别用arr[y]和arr[y+1]标识,x的值依次为1,2,...,5,对于每一个x,y的值依次为1,2,...5-x。

冒泡排序 例:{8 , 2 , 3 , 7 , 1}的排序过程如下所示:

arr={8,2,3,7,1}

arr={2,8,3,7,1}

arr={2,3,8,7,1}

arr={2,3,7,8,1}

arr={2,3,7,1|8}

arr={2,3,7,1|8}

arr={2,3,7,1|8}

arr={2,3,1|7,8}

arr={2,3,1|7,8}

arr={2,1|3,7,8}

arr={1,2,3,7,8}

代码如下:

import java.util.*;
/*
对给定数组进行排序。
{8,2,7,3,1}
*/
class ArrayTest2 
{
	/*
	选择排序。
	内循环结束一次,最值出现头角标位置上。
	*/
	public static void selectSort(int[] arr)
	{
		for (int x=0; x<arr.length-1 ; x++)
		{
			for(int y=x+1; y<arr.length; y++)
			{
				if(arr[x]>arr[y])//小到大进行排序
				{
					swap(arr,x,y);
				}
			}
		}
	}
	/*
	冒泡排序
	*/
	public static void bubbleSort(int[] arr)
	{
		for(int x=0; x<arr.length-1; x++)
		{									
			for(int y=0; y<arr.length-x-1; y++)//-x:让每一次比较的元素减少,-1:避免角标越界。
			{
				if(arr[y]<arr[y+1])//大到小排序
				{
					swap(arr,y,y+1);
				}
			}
		}
	}
	/*
	发现无论什么排序。都需要对满足条件的元素进行位置置换。
	所以可以把这部分相同的代码提取出来,单独封装成一个函数。
	*/
	public static void swap(int[] arr,int a,int b)
	{
		int temp = arr[a];
		arr[a] = arr[b];
		arr[b] = temp;
	}
	public static void main(String[] args)
	{
		int[] arr = {8 , 2 , 3 , 7 , 1};
		//排序前;
		printArray(arr);
		//排序
		selectSort(arr);
		//排序后:
		printArray(arr);
		bubbleSort(arr);
		//Arrays.sort(arr);//java中已经定义好的一种排序方式。开发中,对数组排序要使用该句代码。直接调用即可。
		//排序后:
		printArray(arr);
			
	}
	public static void printArray(int[] arr)
	{
		System.out.print("[");
		for(int x=0; x<arr.length; x++)
		{
			if(x!=arr.length-1)
				System.out.print(arr[x]+", ");
			else
				System.out.println(arr[x]+"]");
		}		
	}
}


5、反转

/*
对给定的数组进行反转。
{3,1,5,6,2} --->
{2,6,5,1,3}
*/
class  ArrayTest3
{
	public static void main(String[] args) 
	{
		int[] arr = {3,1,5,6,2};
		printArray(arr);
		//反转后;
		reverseArray(arr);
		printArray(arr);
	}
	public static void reverseArray(int[] arr)
	{
		for(int start=0,end=arr.length-1; start<end ; start++,end--)
		{
			/*
			int temp = arr[start];
			arr[start] = arr[end];
			arr[end] = temp;
			*/
			swap(arr,start,end);
		}
	}
	public static void swap(int[] arr,int a,int b)
	{
		int temp = arr[a];
		arr[a] = arr[b];
		arr[b] = temp;
	}
	public static void printArray(int[] arr)
	{
		System.out.print("[");
		for(int x=0; x<arr.length; x++)
		{
			if(x!=arr.length-1)
				System.out.print(arr[x]+", ");
			else
				System.out.println(arr[x]+"]");
		}		
	}
}


6、折半查找


有一个有序的数组,想要将一个元素插入到该数组中,还要保证该数组是有序的。如何获取该元素在数组中的位置。


import java.util.*;
class Demo 
{
	public static void main(String[] args) 
	{
		int[] arr = {2,4,5,7,8,19,32,45};
		int index = getIndex(arr,10);
		System.out.println("index="+index);
	}
	public static int getIndex(int[] arr,int key)//折半查找获取  
	{
		int min = 0,max = arr.length-1,mid=(min+max)/2;
		while(min<=max)
		{
			mid = (max+min)>>1;
			if(key>arr[mid])
				min = mid + 1;
			else if(key<arr[mid])
				max = mid - 1;
			else
				return mid;//如果数组中有这个数了,直接返回该数所在位置,也就是插入位置 
		}
		return min;//获取插入角标 
	}
}
 


七、二维数组:


二维数组[][]
格式1:int[][] arr = new int[3][2];
 定义了名称为arr的二维数组
 二维数组中有 3个一维数组
 每一个一维数组中有 2个元素
 一维数组的名称分别为arr[0], arr[1], arr[2]
 给第一个一维数组1脚标位赋值为78写法是:arr[0][1] = 78;
格式2:int[][] arr = new int[3][];
 二维数组中有 3个一维数组
 每个一维数组都是默认初始化值null
 可以对这个三个一维数组分别进行初始化
  arr[0] = new int[3];
  arr[1] = new int[1];
  arr[2] = new int[2];

格式3:int[][] arr = {{3,8,2},{2,7},{9,0,1,6}};
l 定义一个名称为arr的二维数组
l 二维数组中的有三个一维数组
l 每一个一维数组中具体元素也都已初始化
l 第一个一维数组 arr[0] = {3,8,2};
l 第二个一维数组 arr[1] = {2,7};
l 第三个一维数组 arr[2] = {9,0,1,6};
l 第三个一维数组的长度表示方式:arr[2].length;

注意特殊写法情况:int[] x,y[]; x是一维数组,y是二维数组。


lint[] arr = new int[3];

l直接输出arr[0]的结果就是0

l如果直接输出arr结果是[I@64883c

l@符号左边是引用数据类型所对应的类型

l[代表数组类型的引用I代表的是int类型的元素

l@右边是通过哈希算法算出的地址值

lint[][] arr1 = new int[3][2]


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值