Java菜鸟学习之路之基础编程---数组使用及内存分配详解(六)

1.数组


  •  定义:

                 是多个相同类型得数据按一定顺序排列得集合,并使用一个名字命名,并通过编号得方式对这些数据进行统一管理

 

  •  常见概念:

    • 数组名
    • 角标、下标(或索引)    
    • 元素
    • 数组得长度(元素得个数)

 

  •  数组得特点:

                数组是有序排列得 

 

  • 说明:

    1.数组本身是引用数据类型,而数组中得元素可以是任意数据类型,包括基本数据类型和引用数据类型

    2.创建数组对象会在内存中开辟一整块连续得空间,而数组中引用得是这块连续空间得首地址

    3.数组得长度一旦确定。就不能修改

    4.可以直接通过下标(或索引)得方式调用指定位置得元素,速度很快

     
  • 分类:

    • 按照维度:一维数组、二维数组、三维数组
       
    • 按照元素得数据类型分:基本数据类型元素得数组、引用数据类型元素得数组(即对象数组)


1.1 一维数组


1.1.1 使用

  1. 一维数组得声明和初始化
  2. 如何调用数组指定位置得元素
  3. 如何获取数组得元素
  4. 如何遍历数组
  5. 数组元素得默认初始化值
  6. 数组得内存解析

一维数组使用1.2.3.4得测试用例:

public class Array_Test {
	public static void main(String[] args) {
		int num;	//普通整型变量得声明
		num = 10;	//初始化
		int num1 = 10;	//声明 + 初始化
		//1.一维数组得声明和初始化
		//声明方式1,创建数组对象时指定元素和长度得数组声明
		//数组得初始化和数组元素得赋值操作同时进行
		int[] arr;	//声明
		//1.1 静态初始化
		arr = new int[] {1,2,3,4};	//初始化,要使用引用数据类型必须创建对象来使用其中得属性和方法 
		
		//声明方式2,创建数组对象时指定长度(最多可以存储元素得个数),但是不指定其中得具体元素得数组声明
		//1.2 动态初始化
		//数组得初始化和数组元素得赋值操作分开进行
		String[] names = new String[5];	//声明 + 初始化,指定数组的长度和数据类型,但是具体元素暂不进行赋值
		
		//总结:数组一旦初始化完成,那么长度就是可以确定得了
		
		//2.调用数组指定位置得元素:通过角标方式来进行查找
		//Java中数组得角标(索引)是从0开始得,那么数组最大调用角标就为:数组得长度 - 1
		names[0] = "张三";	//数组中得第一个元素的角标为0
		names[1] = "李四";
		names[2] = "王五";
		names[3] = "赵六";
		names[4] = "孙七";	//数组中得最后一个元素得角标为:数组长度 - 1 = 4
		//names[5] = "钱八";	//出现运行时错误,错误信息为 java.lang.ArrayIndexOutOfBoundsException: 5(数组角标越界)
	
		//3.如何获取数组得长度
		//属性:length
		System.out.println(names.length);	//5
	
		//4.如何去遍历数组元素
		
		  for(int i = 0;i < names.length;i++) { 
			  System.out.print(names[i] + " "); 
		  }
		//输出:张三 李四 王五 赵六 孙七 
	}
}

一维数组使用5得测试用例:

/*5.数组元素得默认初始化值:
 * 	>数组元素是整型:0
 * 	>数组元素是浮点型:0.0
 * 	>数组元素是char字符类型:0或字符		不是'0'字符,而是ASCII码值为0处得字符
 * 	>数组元素是布尔类型:fasle
 *
 *	>数组元素是引用数据类型得时候:null
 *
 *6.数组得内存解析:
 * */
public class ArrayTest1 {
	//5.数组元素得默认初始化值
	public static void main(String[] args) {
		int[] arr = new int[5];
		for(int i = 0;i < arr.length;i++) {
			System.out.print(arr[i] + " ");	//0 0 0 0 0
		}
		
		System.out.println();
		
		char[] arr1 = new char[5];
		for(int i = 0;i < arr1.length;i++) {
			System.out.print(arr1[i] + "---");	//0 0 0 0 0
		}

		System.out.println();
		
		String[] arr2 = new String[6];
		System.out.println(arr2[0]);
	}
}


数组元素内存解析:

具体执行代码:

       (1)int[] arr = new int[]{1,2,3};

       (2)String[] arr1 = new String[6];

       (3)arr1[1] = “张三”;

       (4)arr1[2] = “李四”;

       (5)arr1 = new String[3];

注意:只要见到new关键字 + 类名就意味着在堆内存中创建对象


一维数组得内存解析:

 


一维数组得课后练习测试用例:

import java.util.Scanner;

/*从键盘读入学生成绩,找出最高分,并输出学生成绩等级
 * >成绩 = 最高分 - 10 	等级为'A'
 * >成绩 = 最高分 - 20 	等级为'B'
 * >成绩 = 最高分 - 30 	等级为'C'
 * >其余					等级为'D'
 * 
 * */
public class ArrayDemo1 {
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		System.out.print("请输入学生得个数: ");
        //1.获取学生个数
		int number = scan.nextInt();
		System.out.println("请输入" + number +"个成绩");
        
        //2.定义一维数组型变量来存储学生成绩
		int[] score = new int[number];
	
        //3.从控制台获取学生成绩
                int i = 0;
		while(i < score.length) {
			score[i] = scan.nextInt();;
			i++;
		}
        
        //4.获取最高分
		int maxScore = 0;
		for(int j = 0;j < score.length;j++) {
			if(maxScore <= score[j]) {
				maxScore = score[j];
			}
		}
		System.out.println("最高分是" + maxScore);
		//5.获取各个学生得等级
		String level = "";
		for(int k = 0;k < score.length;k++) {
			if(maxScore - score[k] <= 10) {
				level = "A";
			}else if(maxScore - score[k] <= 20) {
				level = "B";
			}else if(maxScore - score[k] <= 30) {
				level = "C";
			}else {
				level = "D";
			}
			System.out.println("sudent " + k + " score is " + score[k] + " grade is " + level);
		}
	}
}

 

1.2 多维数组


1.2.1 理解:

        对于二维数组得理解,可以看成是是一个一维数组array又作为另一个数组array1得元素而存在。其实,从数组底层的运行机制来看,其实没有多维数组(只不过一维数组里面得元素还是一个一维数组,所以称之为二维数组)

 

1.2.2 使用: 

  1. 二维数组得声明和初始化
  2. 如何调用数组指定位置得元素
  3. 如何获取数组得元素
  4. 如何遍历数组
  5. 数组元素得默认初始化值
  6. 数组得内存解析

二维数组使用1,2,3,4的测试用例:

public class ManyArray_Test {
	public static void main(String[] args) {
		//1.二维数组得声明和初始化(一个[]代表数组中得一个维度)
		int[] arr = new int[] {1,2,3};	//一位数组得静态初始化
		
		int[][] arr1 = new int[][] {{1,2,3},{5},{6,7}};		//二维数组得静态初始化
		//{1,2,3}又是一个数组,代表外层数组中得第一个元素
		//{5}又是一个数组,代表外层数组中得第二个元素
		//{6,7}又是一个数组,代表外层数组中得第三个元素
		
		//动态初始化1
		String[][] arr2 = new String[3][2];
		//第一维为3,指定外层数组中有三个元素(外层数组得每一个元素为一维内层数组)
		//第二维为2,指明内层数组中有两个元素(内层数组作为外层数组中得元素而存在)
		
		//动态初始化2
		String[][] arr3 = new String[3][];
		//第一维为3,指定外层数组中有三个元素(外层数组得每一个元素为一维内层数组)
		//第二维空间可以在创建二维数组对象时暂不指定具体长度,等到有具体需求得时候可在定义
		//注意:二维数组得第一维维度必须指定长度,否则编译不通过,第二维维度可指定也可不指定
		
		/*错误情况:
		 * int[][] arr = new int[][4];	
		 * //错误,在定义二维数组得时候,第一维长度必须指定
		 * 
		 * int[4][3] arr = new int[][3];	
		 * //错误,前面定义变量[][]只是进行声明得作用,里面不能对维度进行初始化
		 * 
		 * int[][] arr = new int[4][3]{{1,2,3},{5},{6,7}};
		 * 错误,静态初始化和动态初始化混杂,啥也不是,定义是要么不定义具体维度,给出具体数组元素。要么只定义具体维度,不给出数组中得具体元素
		 * */
		
		//其他正确情况:
		int arr4[][] = new int[4][3];	
		//[][]可以放在变量名之后声明
		
		int []arr5[] = new int[4][3];	
		//[][]可以分别一前一后定义在变量名前后位置,但是这样做不符合通常的定义规范,不建议使用
	
		int[][] arr6 = {{1,2,3},{5},{6,7}};
		//java虚拟机进行自动类型推断,根据前驱定义,识别方面定义得数据与前驱一致
		//声明 + 初始化分开来写,那么就不能进行自动类型推断了,会报错 
		
		//2.如何调用数组中得指定位置上得元素
		System.out.println(arr1[0][1]);		//2
		//调用二维数组arr1得外层数组元素位置为0,内层数组元素位置为1上的元素
		
		System.out.println(arr2[1][1]);		//null默认初始化值
		//调用索引位置为1,1得元素,实际位置是第二行第二列得元素
		
		arr3[1] = new String[4];	
		//为arr3数组中得索引为1,实际位置为2得元素开辟第二维空间,并指定长度
		System.out.println(arr3[1][1]); 	//运行出错,空指针异常
		//想调用索引位置为1,1得元素,但是第二维中还未开辟空间,所以指向了一个寂寞,指向为空
		//如果想进行调用,可以在调用此位置元素之前,指定第二维,为第二维开辟内存空间
	
		//3.获取数组的长度
		System.out.println(arr1.length);	//3
		//获取外层数组可存储元素(这里的每一个元素又指内层的一个一维数组)个数(长度)
	
		System.out.println(arr1[0].length);	//3
		//获取外层数组元素指定索引处为0,内层数组长度(可存储数据的容量大小)
	
		//4.如何遍历二维数组:使用双层for循环
		for(int i = 0;i < arr1.length;i++) {	//外层循环控制外层数组索引
			for(int j = 0;j < arr1[i].length;j++) {		//内层循环控制内层数组索引
				System.out.print(arr1[i][j] + " ");
				//第一次内层循环执行完输出:1 2 3
				//第二次内层循环执行完输出:5
				//第三次内层循环执行完输出:6 7
			}
			System.out.println();
		}
	}
}


二维数组使用5的测试用例:

/*二维数组的使用:
 * 	规定:外层数组分为外层数组元素和内层数组元素
 * 		int[][] arr = new int[4][3];
 * 		外层元素:arr[0]、arr[1]、...等
 * 		内层元素:arr[0][0]、arr[1][1]、...等
 * 	
 * 	5.数组元素的默认初始化
 * 		针对于int[][] arr = new int[4][3];的初始化方式
 * 		外层元素:地址值
 * 		内层元素:根据定义二维数组的数组的数据类型来确定,两者保持一致(与一维数组默认初始化情况相同)
 * 
 * 		针对于int[][] arr = new int[4][];的初始化方式
		外层元素:null(每个元素是一个数组,数组本身就是引用数据类型,那么默认初始话值为null)
		内层元素:不能调用,因为第一维为null,那么它指向第二维(还未开辟内存空间),肯定就指向了寂寞,运行时出错,报出空指针异常的错误
 * 	
 * 	6.数组的内存解析
 * 
 * 
 * 
 * */
public class ManyArray1_Test {
	public static void main(String[] args) {
		//5.默认初始化
		int[][] arr = new int[4][3];
		System.out.println(arr[0]);		//[I@7852e922
		//最外层存放的是元素(内层数组)的首地址值,指向的是堆内存中内层数组的首地址值
		//地址值解析:'['代表存放的元素为一维数组类型,'I'代表的是元素的数据类型为int整型数据,'@7852e922'代表随机地址值
		
		System.out.println(arr[0][0]);	//0
		//已经到了最内层了,默认初始化的值与定义的二维数组时的数据类型相一致
		
		System.out.println(arr);	//[[I@4e25154f
		
		//6.内存解析
	}
}


二维数组元素内存解析:

具体执行代码:

       (1)int[] [] arr1 = new int [4] [ ];

       (2)arr1[1] = new int[]{1,2,3};

       (3)arr1[2] = new int[4];

       (4)arr1[2] [1] = 30;


二维数组执行语句解析内存图:

 


注意例题:

int[]x,y[];在给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;                     //错误

 

解析:

连续赋值含义理解清楚,例如:int x,y = 10;将x和y变量都定义为int整型的数据类型,并且都赋值为10,那么int[] x,y;就是将x和y都定义为int整型的一维型数组变量,

那么int[] x,y[];就是将前者定义为整型的一维型数组变量x,因为在定义y的时候,y自身也带了一个维度,再加上前面整体定义的一个维度,那么y就是整型的二维数组变量。然后接下来就分别理清楚各层其中存放的元素类型,然后把握赋值语句的要素,小到大,自动类型提升,大到小,强制类型转换,基本数据类型之间可以转换,基本数据类型和引用数据类型之间不能相互赋值,但是能相互转换。

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值