java----Java数组

Java数组
一、 数组中常出现的异常
class Demo
{
	public static void main(String []args){
		int []x = new int[3];
		int []y = new int[3];
		y[1] = 89;
		x = null;
		sop(x[1]);
	}
}
疑问x[1]是多少呢?

NullPointerException空指针异常:当引用没有任何指向,值为null的情况,该引用还在用于操作实体,就会报该异常。
NullPointerException异常。因为x被赋值为null,原来指向new int[3]的引用没有了。所以就会抛空指针异常。
图示

int []arr = new int[]{3,1,6,5,4};//静态初始化方式
		int []arr = {3,1,6,5,4};
class Demo
{
	public static void main(String []args){
		int []arr = new int[3];
		System.out.println(arr[3]);
	}
}

ArrayIndexOutOfBoundsException数组角标越界异常。因为操作数组时,访问到了数组中不存在的角标。
ArrayIndexOutOfBoundsException异常。因为角标从0开始,而数组长度为3,没有为3的角标位。操作超过了数组范围,所以报数组角标越界异常。
二、数组的操作
遍历:获取数组中的元素,通常会用到遍历。
length:作为数组中的一个属性,可以直接获取到元素个数。使用方式:数组名称.length。
需求:定义功能,用于打印数组中的元素,元素间用 隔开。
class Demo
{
	public static void main(String []args){
		int []arr = {1,2,3,4,5,6};
		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.println(arr[x]+"]");
			else
				System.out.print(arr[x]+",");
		}
	}
}
class Demo
{
	public static void main(String []args){
		int []arr = {1,2,3,4,5,6};
		System.out.println(arr);
	}
}

[I@de6ced的含义:[I@de6ced是数组存放在堆内存中的地址值,[”表示是数组类型,“I”表示是int类型,“@”表示是引用,“de6ced”表示数组存放的内存地址。该值是由哈希算法得来。
三、练习
给定一个数组{5,1,6,4,2,8,9}。获取数组中的最大值以及最小值。
思路:
1、获取最值需要进行比较,每一次比较都会有一个较大的值,因为该值不确定。
2、让数组中的每一个元素都和这个变量的值进行比较。
3、当所以的元素都比较完成,那么该变量中存储的就是数组中的最大值了。
步骤:
1、 定义变量:初始化为数组中的任意一个元素即可。
2、通过循环语句对数组进行遍历。
3、在遍历过程中定义判断条件。如果遍历到的元素比变量中的元素大,就赋值给该变量。
需要定义一个功能来完成,以便提高复用性。
1、明确结果:数组中的元素int。
2、未知内容:一个数组int[]。
class Demo
{
	public static void main(String []args){
		int []arr = {3,9,2,4,1};
		System.out.println("Max="+getMax(arr));
		System.out.println("Min="+getMin(arr));
	}
	//获取最大值
	public static int getMax(int []arr){
		int max = arr[0];
		for(int x=0;x<arr.length;x++){
			if(max<arr[x])
				max = arr[x];
		}
		return max;
	}
	//获取最小值
	public static int getMin(int []arr){
		int min = arr[0];
		for(int x=0;x<arr.length;x++){
			if(min>arr[x])
				min = arr[x];
		}
		return min;
	}
}
获取最大值的另一种方式:
疑问可不可以将临时变量初始化为0呢?
:可以,这种方式其实是初始化为数组中任意一个角标。
class Demo
{
	public static void main(String []args){
		int []arr = {3,9,2,4,1};
		System.out.println("Max="+getMax(arr));
		System.out.println("Min="+getMin(arr));
	}
	//获取最大值
	public static int getMax(int []arr){
		int max = 0;
		for(int x=0;x<arr.length;x++){
			if(arr[max]<arr[x])
				max = x;
		}
		return arr[max];
	}
	//获取最小值
	public static int getMin(int []arr){
		int min = 0;
		for(int x=0;x<arr.length;x++){
			if(arr[min]>arr[x])
				min = x;
		}
		return arr[min];
	}
}
获取double类型数组中的最大值,因为功能一致,所以定义相同的函数名称,以重载形式存在。
public static double getMax(double []arr){
		int min = 0;
		for(int x=0;x<arr.length;x++){
			if(arr[min]<arr[x])
				min = x;
		}
		return arr[min];
	}
四、 数组的排序
需求:对给定数组进行排序:{5,1,6,4,2,8,9}
选择排序
图示:

class Demo
{
	public static void main(String []args){
		int []arr = {5,1,6,4,2,8,9};
		printArray(arr);
		selectSort(arr);
		printArray(arr);
	}
	//选择排序算法
	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])
					change(x,y,arr);
			}
		}
	}
	//交换位置
	public static void change(int a,int b,int []arr){
		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.println(arr[x]+"]");
			else
				System.out.print(arr[x]+",");
		}
	}
}
选择排序特点:内循环结束一次,最值出现在头角标位置上。
冒泡排序
图示:

class Demo
{
	public static void main(String []args){
		int []arr = {5,1,6,4,2,8,9};
		printArray(arr);
		bubbleSort(arr);
		printArray(arr);
	}
	//冒泡排序算法
	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++){
				if(arr[y]>arr[y+1])
					change(y,y+1,arr);
			}
		}
	}
	//交换位置
	public static void change(int a,int b,int []arr){
		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.println(arr[x]+"]");
			else
				System.out.print(arr[x]+",");
		}
	}
}
冒泡排序法特点:最值出现在最后位置上。
最快的排序算法:希尔排序。
在java.util包中,已经定义好了一种排序方式对数组排序——Array.sort(数组);
五、数组的查找操作
需求:定义功能,获取key第一次出现在数组中的位置。如果返回-1,那么代表该key在数组中不存在。
class Demo
{
	public static void main(String []args){
		int []arr = {5,1,6,4,2,8,9};
		System.out.println(find(arr,8));
	}
	public static int find(int []arr,int key){
		for(int x=0;x<arr.length;x++){
			if(arr[x]==key)
				return x;//如果和指定的key相等,则返回对应角标。
		}
		return -1;//如果没有找到则返回-1。
	}
}
科普一下:用-1来标识数组中没有找到的情况,这是操作数组的惯例。
折半查找:提高效率,但是必须要保证该数组是有序的。
class Demo  
{  
	public static void main(String []args){  
		int []arr = {2,3,6,8,9,10,15,23,32,100};  
		System.out.println(halfSearch(arr,1));  
	}  
	public static int halfSearch(int []arr,int key){  
		int min = 0,max = arr.length-1,mid = (min+max)>>1;
		//min为数组头角标,另max为数组最后一个元素的角标,mid为中间元素角标右移一位比除以2高效。  
		while(arr[mid]!=key){
		//当中间值不能与key的时候开始循环  
		if(key<arr[mid])
			//当key小于中间值时,把尾角标变为中间角标,因为中间值mid已经比过了所以要mid-1; 
			max = mid-1; 
		if(key>arr[mid])
			//当key小于中间值时,把尾角标变为中间角标,因为中间值mid已经比过了所以要mid-1;   
			min = mid+1;
		if(min>max)  
		return -1;  
		mid = (min+max)>>1;  
		}  
		return mid;  
	}  
} 
另一种方式
class Demo
{
	public static void main(String []args){
		int []arr = {2,3,6,8,9,10,15,23,32,100};
		System.out.println(halfSearch(arr,101));
	}
	public static int halfSearch(int []arr,int key){
		int min = 0,max = arr.length-1,mid;
		while(min<=max){
			mid = (min+max)>>1;
			if(key<arr[mid])
				max = mid-1;
			else if(key>arr[mid])
				min = mid+1;
			else
				return mid;
		}
		return -1;
	}
}
练习:有一个有序的数组,想要将一个元素插入到该数组中。还要保证该数组还是有序的。如何获取该元素在数组中的位置。
class Demo
{
	public static void main(String []args){
		int []arr = {2,3,6,8,9,10,15,23,32,100};
		System.out.println(halfSearch(arr,7));
	}
	public static int halfSearch(int []arr,int key){
		int min = 0,max = arr.length-1,mid;
		while(min<=max){
			mid = (min+max)>>1;
			if(key<arr[mid])
				max = mid-1;
			else if(key>arr[mid])
				min = mid+1;
			else
				return mid;
		}
		return min;
	}
}
练习:十进制转二进制
class Demo
{
	public static void main(String []args){
		toBin(4);
	}
	public static void toBin(int num){
		StringBuffer sb = new StringBuffer();//定义一个临时容器
		while(num!=0){
			int x = num&1;
			num = num>>>1;
			sb.append(x);
		}
		System.out.println(sb.reverse());//翻转容器
	}
}
原理:
图示

练习:十进制转十六进制
class Demo
{
	public static void main(String []args){
		toHex(60);
	}
	public static void toHex(int num){
		//利用查表法,先要定义一个表。
		char[] chs = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
		//定义临时容器
		StringBuffer sb = new StringBuffer();
		while(num!=0){
			//二进制中的4为代表一个十六进制,1111的对应16进制是15.&1111所得的值就是相应的16进制的一位
			int x = num&15;
			//继续右移4位,为的是获取下一个16进制位。
			num = num>>>4;
			//将所得值利用查表法,装到容器里。
			sb.append(chs[x]);
		}
		System.out.println(sb.reverse());
	}
}
原理:
图示

class Demo
{
	public static void main(String []args){
		toHex(60);
	}
	public static void toHex(int num){
		//利用查表法,先要定义一个表。
		char[] chs = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
		//定义临时容器
		StringBuffer sb = new StringBuffer();
		while(num!=0){
			//二进制中的4为代表一个十六进制,1111的对应16进制是15.&1111所得的值就是相应的16进制的一位
			int x = num&15;
			//继续右移4位,为的是获取下一个16进制位。
			num = num>>>4;
			//将所得值利用查表法,装到容器里。
			sb.append(chs[x]);
		}
		System.out.println(sb.reverse());
	}
}
疑问神马是查表法
查表法:将所有的元素临时存储起来,建立对应关系。每一次&15后的值作为索引去查建立好的表,就可以找到对应的元素。
疑问这个表怎么建立呢?
可以通过数组的形式来定义。采用StringBuffer reverse功能来完成。
功能优化:发现查表法不仅适应与十进制转十六进制,同样也适合八进制和二进制。
class Demo
{
	public static void main(String []args){
		toOct(8);
	}
	//十进制转二进制
	public static void toBin(int num){
		trans(num,1,1);
	}
	//十进制转八进制
	public static void toOct(int num){
		trans(num,7,3);
	}
	//十进制转十六进制
	public static void toHex(int num){
		trans(num,15,4);
	}
	public static void trans(int num,int base,int offset){
		//num为需要转换的数,base为相&的数,offset为偏移量。
		//利用查表法,先要定义一个表。
		char[] chs = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
		//定义临时容器
		StringBuffer sb = new StringBuffer();
		while(num!=0){
			int x = num&base;
			num = num>>>offset;
			sb.append(chs[x]);
		}
		System.out.println(sb.reverse());
	}
}
六、二维数组
格式1:int [][] arr = new int[3][2];
1、定义了名称为arr的二维数组。
2、二维数组中游3个一维数组。
3、每一个一维数组中有2个元素。
4、一维数组的名称分别为arr[0],arr[1],arr[2]。
5、给第一个一维数组1角标位赋值为78,写法是arr[0][1] = 78;。
格式2:int [][] arr = new int [3][];
1、二维数组中有3个一维数组。
2、每个一维数组都是默认初始化值null。
可以对这三个一维数组分别进行初始化。
arr[0] = new int[3];
arr[1] = new int[1];
arr[2] = new int[2];
		int [][] arr = new int[3][4];
		System.out.println(arr);

[[I@de6ced的含义:“[[”表示是二维数组,“I”代表数据类型为int,“@”表示引用。“de6ced”表示地址值。
		int [][] arr = new int[3][4];
		System.out.println(arr[0]);

[I@de6ced的含义:“[”表示是一维数组,“I”代表数据类型为int,“@”表示引用。“de6ced”表示地址值。
		int [][] arr = new int[3][];
		System.out.println(arr);

		int [][] arr = new int[3][];
		System.out.println(arr[0]);

		int [][] arr = new int[3][];
		arr[0] = new int[3];
		arr[1] = new int[1];
		arr[2] = new int[2];
内存中的存储:
图示

		System.out.println(arr.length);//打印的是二维数组的长度
		System.out.println(arr[0].length);//打印的是第一个一维数组的长度
累加:
class Demo
{
	public static void main(String []args){
		//静态初始化
		int [][] arr = {{3,5,1,7},{2,3,5},{6,1,8,2}};
		int sum = 0;
		//控制外角标
		for(int x=0;x<arr.length;x++){
			//控制内角标
			for(int y=0;y<arr[x].length;y++){
				//获取元素并累加
				sum = sum+arr[x][y];
			}
		}
		System.out.println("sum="+sum);
	}
}
练习:
int [] x,y[];判断赋值对错。
a、x[0] = y;
b、y[0] = x;
c、y[0][0] = x;
d、x[0][0] = y;
e、y[0][0] = x[0];
f、x = y;
a错,b对,c错,d错,e对,f错。
一维数组的声明:int []x;或int x[];
二维数组的声明:int [][]x;或int x[][];还有int []y[];(面试)。
上题中int [] x,y[];相当于
int []x;
int []y[];
所以y其实是二维数组。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值