黑马程序员 java学习笔记——数组

---------------------- ASP.Net+Android+IO开发S.Net培训、期待与您交流! ----------------------

数组的定义

概念:同一种类型数据的集合,其实数组就是一个容器。
优点:可以自动给数组中的元素从0开始编号,方便操作这些元素。
定义数组有两种格式:
1、元素类型[] 数组名=new 元素类型[元素个数或数组长度];
示例:int[] arr=new int[5];
2、元素类型[] 数组名=new 元素类型[]{元素,元素,元素,……}
示例:int[] arr=new int[]{1,9,4,6};
int[] arr={1,9,4,6}
public class Test1 {
	public static void main(String[] args){
		//x是数组类型
		//x[0]是int型
		int[] x=new int[5];  //在堆内存中创建一个长度为5的数组
		for(int i=0;i<5;i++){
			System.out.print(x[i]);
		}
	}
}
//output:00000
//由输出结果可知,数组中的元素在未赋值时有默认值,为0
//char类型的数组,元素的默认值为'\u0000',unicode表中的空格

数组的内存分配及特点

java程序在运行时,需要在内存中的分配空间。为了提高运算效率,又对空间进行了不同区域的划分,因为每一篇区域都有特定的处理数据方式和内存管理方式。
栈内存:用于存储局部变量,当数据使用完,所占空间会自动释放。
定义在方法中的变量,定义在方法参数上的变量,定义在for循环中的变量,都是局部变量。
堆内存:数组和对象,通过new建立的实例都存放在堆内存中。
每一个实体都有内存地址值
实体中的变量都有默认初始化值
实体不在被使用,会在_不确定_的时间内被垃圾回收器回收。
内存中除了堆内存和栈内存外,还有方法区,本地方法区和寄存器。

public class Test1 {
	public static void main(String[] args){
		int[] arr=new int[4]; //将堆内存中的数组指向栈内存中的数组变量x。
		int[] arr1=arr;  //将内存地址x传递给y
		arr[0]=5;
		arr1[0]=9;
		arr=null; //将数组变量x清除,也就是说它不在指向堆内存中的数组
		System.out.println(arr1[0]);
	}
}
//output:9

上面程序的内存图如下

数组中的常见异常

1、ArrayIndexOutOfBoundsException:数组角标越界异常
如int[] arr=new int[3];
System.out.println(arr[3]);
由于这段代码不存在语法错误,并未创建数组,编译期间不会报错,但当运行时,就会报错ArrayIndexOutOfBoundsException,因为它访问到了数组中不存在的角标。
2、NullPointerException:空指针异常
如int[] arr=new int[3];
arr=null;
System.out.println(arr[3]);
当引用没有任何指向值,为null的情况,该引用还在用于操作实体,就会产生NullPointerException。

数组的常见操作

遍历

public class Test1 {
	public static void main(String[] args){
		//数组的操作
		//获取数组中的元素,通常会用到遍历
		int[] x=new int[]{68,81,35,64,22};  
		for(int i=0;i<x.length;i++){  //x.length为数组x的长度
			System.out.println(x[i]);
		}
	}
}
//output:
//68
//81
//35
//64
//22

获取最值

/*
 * //给定数组{68,81,35,64,22,39},获取最大值与最小值
 * 思路:
	1、获取最值需要进行比较。每一次比较都会有一个较大值,因为该值不确定,通过一个变量进行临时存储。
	2、让数组中的每一个元素都和这个变量中的值进行比较。如果大于了变量中的值,就用该变量记录较大值
	3、当所有的元素都比较完成,那么该变量中存储的就是数组中的最大值

	步骤:
	1、定义变量,初始化为数组中任意一个元素即可
	2、通过循环语句对数组进行遍历
	3、在变量过程中定义判断条件,如果遍历到的元素比变量中的元素大,就赋值给该变量

	需要定义一个功能来完成,以便提高复用性
	1、明确返回值,数组中的最大元素int型
	2、未知内容:一个数组,int[]
	
	最小值与最大值的思路与步骤相似。
 * */
public class Test1 {
	public static void main(String[] args){
		int[] x=new int[]{68,81,35,64,22,39};  
		System.out.println("max="+getMax(x));
		System.out.println("min="+getMin(x));
		}
	/*
	 * 获取最大值
	 * @param arr 接收一个int型数组
	 * @return 返回数组中的最大值
	 * */
	public static int getMax(int[] arr){
		int max=arr[0];
		for(int i=1;i<arr.length;i++){
			if(arr[i]>max)
				max=arr[i];
		}
		return max;
	}
	/*
	 * 获取最小值
	 * @param arr 接收一个int型的数组
	 * @return 返回数组中的最大值
	 * */
	public static int getMin(int[] arr){

		//将min定义为数组的角标,而不是元素。
		int min=0;
		for(int i=1;i<arr.length;i++){
			if(arr[i]<arr[min])
				min=i;
		}
		return arr[min];
	}
}
//output:
//max=81
//min=22

排序:选择排序和冒泡排序

import java.util.Arrays;
public class Test1 {
	public static void main(String[] args){
		int[] x=new int[]{68,81,35,64,22,39};  
		System.out.println(Arrays.toString(x));
		selectSort(x);
		System.out.println(Arrays.toString(x));
		bubbleSort(x);
		System.out.println(Arrays.toString(x));
	}

	//选择排序
	//第一圈时,最值出现在第一位
	public static void selectSort(int[] arr){   //x指向堆中对象,操作对象,此处不用返回值。
		for(int i=0;i<arr.length-1;i++){
			for(int j=i+1;j<arr.length;j++){
				if(arr[i]>arr[j]){
					swap(arr,i,j);
				}
			}
		}
	}

	//冒泡排序
	//第一圈时,最值出现在最后位
	public static void bubbleSort(int[] arr){   
		for(int i=0;i<arr.length-1;i++){
			for(int j=0;j<arr.length-i-1;j++){
				if(arr[j]<arr[j+1]){
					swap(arr,j,j+1);
				}
			}
		}
	}
	public static void swap(int[] arr,int a,int b){  //位置置换功能的抽取
		int temp=arr[a];
		arr[a]=arr[b];
		arr[b]=temp;
	}
}
//output:
//[68, 81, 35, 64, 22, 39]
//[22, 35, 39, 64, 68, 81]
//[81, 68, 64, 39, 35, 22]

折半查找

public class Test1 {
	public static void main(String[] args){
		int[] x=new int[]{68,81,35,64,22,39};  
		int index=getIndex(x,35);
		System.out.println(index);
		
	}
	/*
	 *当数组按照顺序排列时,折半查找某一个数
	 * @param arr key 接收一个int型数组和一个int型数值
	 * @return 返回一个int型值
	 */
	public static int halfSearch_2(int[] arr,int key){
		int min=0,max=arr.length-1,mid;
		while(min<=max){
			mid=(min+max)>>1;
			if(key>arr[mid])
				min=mid+1;
			if(key<arr[mid])
				max=mid-1;
			else
				return mid;
		}
		return -1;
	}
	/*
	 * 当数组按照顺序排列时,折半查找某一个数
	 * @param arr key 接收一个int型数组和一个int型数值
	 * @return 返回一个int型值
	 * */
	public static int halfSearch_1(int[] arr,int key){
		int min=0,max=arr.length-1,mid=(min+max)/2;
		while(key!=arr[mid]){
			if(key>arr[mid])
				min=mid+1;
			else if(key<arr[mid])
				max=mid-1;
			if(min>max)
				return -1;
			mid=(min+max)/2;	
		}
		return mid;
	}
	/*
	 * 获取key第一次出现在数组中的位置
	 * @param arr key 接收一个int型数组和一个int型值
	 * @return 返回值为int型值
	 * */
	public static int getIndex(int[] arr,int key){
		for(int i=0;i<arr.length;i++){
			if(key==arr[i])
				return i;
		}
		return -1;
	}
}
折半查找的前提是数组是有序的。

进制转换:查表法

/*
 * 用查表法将十进制转换成二进制、八进制、十六进制
 * 经过抽取,从三个方法中抽取出trans方法,表就放在其中。其他三个方法只需要调用它既可
 * */
public class Test1 {
	public static void main(String[] args){
		//toBin(6);
		//toHex(-60);
		toOct(18);
	}
	/*
	 * 将十进制转换成八进制
	 * @param num 接收int型数值
	 * */
	public static void toOct(int num){
		trans(num,7,3);
	}
	/*
	 * 将十进制转换成二进制
	 * @param num 接收int型数值
	 * */
	public static void toBin(int num){
		trans(num,1,1);
	}
	/*
	 * 将十进制转成十六进制
	 * @param num 接收int型数值
	 * */
	public static void toHex(int num){
		trans(num,15,4);
	}
	/*
	 * 从toBin、toOct、toHex中抽取出来的方法,查表法的凝结精华。
	 * @param num base offset 接收三个int型数值
	 * */
	public static void trans(int num,int base,int offset){
		char chs[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
		char arr[]=new char[32];
		int pos=arr.length;
		while(num!=0){
			int temp=num&base;
			arr[--pos]=chs[temp];
			num=num>>>offset;
		}
		for(int i=pos;i<arr.length;i++){
			System.out.print(arr[i]+"");
		}
	}
}

二维数组

定义二维数组的两种格式

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

public class Test1 {
	public static void main(String[] args){
		int[][] arr=new int[3][4];//定义了名称为arr的二维数组,二维数组中有3个一维数组
		  //每一个一维数组中有4个元素

		System.out.println(arr);  //output:[[I@1db9742
		System.out.println(arr[0]); //[I@106d69c
		System.out.println(arr[0][1]); //0

		int[][] arr1=new int[3][];
		System.out.println(arr1); //[[I@52e922
		System.out.println(arr1[0]); //null::::这个才是重点
			//由于arr1[0]没有初始化,所以它是默认初始化。数组是引用数据类型,所以为null

		arr1[0]=new int[3];
		arr1[1]=new int[1];
		arr1[2]=new int[2];
		System.out.println(arr1[0]);//[I@25154f
		System.out.println(arr1.length);//3     //打印的是二维数组的长度
		System.out.println(arr1[0].length);//3	 //打印二维数组中第一个一维数组长度
	}
}

二维数组的求和

public class Test1 {
	public static void main(String[] args){
		int[][] arr={{16,43,52,1},{24,10,32},{2,91,34,55,61,33}};
		int sum=0;
		for(int i=0;i<arr.length;i++){
			for(int j=0;j<arr[i].length;j++){
				sum=sum+arr[i][j];
			}	
		}
		System.out.println("sum="+sum);
	}
}
//output:sum=454

二维数组的小练习:判断正误

小练习:
一维数组的定义方式:int[] x;int x[]
二维数组的定义方式:int[][] x;int x[][];int[] x[];
——————————————————————————
int[] x,y[];x是一维,y是二维
拆开来就是这样int[] x ;int[] y[]
——————————————————————————
a.x[0]=y//error
b.y[0]=x//yes
c.y[0][0]=x//error
d.x[0][0]=y//error
e.y[0][0]=x[0]//yes
f.x=y//error

----------------------  ASP.Net+Android+IO开发S .Net培训 、期待与您交流! ----------------------

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值