Java基础——3、数组(下)——二维数组

接上一章
一维数组的使用

目录

  • 1、二维数组的理解
  • 2、二维数组的使用:
    • 2.1、声明和初始化
    • 2.2、如何调用数组的指定位置的元素
    • 2.3、如何获取数组的长度
    • 2.4、如何遍历数组元素
    • 2.5、数组元素的默认初始化值
    • 2.5、总结:
    • 2.6、二维数组的内存解析
    • 2.6、二维数组练习
  • 3、数组涉及到的算法:
    • 3.1、求数组元素的最大值
    • 3.2、求数组元素的最小值
    • 3.3、求数组元素的总和
    • 3.4、数组的复制(赋值array2变量等于array1)
      • 3.4.1、内存解析
    • 3.4、数组的真正复制
    • 3.5、数组的反转
    • 3.6、数组的查找
    • 3.6.1、数组的线性查找
    • 3.6.2、数组的二分法查找
    • 3.6.3、衡量排序算法的优劣:
    • 十大内部排序算法
    • 3.6.4、数组的排序算法
      • 3.6.4.1、冒泡排序
  • 4、Arrays工具类的使用
    • 4.1、equals方法
    • 4.2、toString方法
    • 4.3、fill方法
    • 4.4、sort方法
    • 4.5、binarySearch查找方法
  • 5、数组中的常见异常
    • 5.1、数组角标越界异常
    • 5.2、空指针异常NullPointerException
      • 情况一:
      • 情况二:
      • 情况三:

1、二维数组的理解

对于二维数组的理解,我们可以看成是一维数组array1作为另一个一维数组array2的元素而存在。
从数组底层的运行机制来看,其实没有多维数组,本质的底层结构还是一维数组

2、二维数组的使用:

2.1、声明和初始化

//一维数组的动态初始化:
		//说明该数组可以存放3个元素
		int[] arr1_1=new int[3];
		
		//	二维数组的动态初始化01:
		//说明该二维数组存了3个数组,其中每一数组里面存放2个元素
		int[][] arr3=new int[3][2];

		//	二维数组的动态初始化02
		//说明该二维数组存了3个数组,其中每一数组里面存放n个元素,具体待定
		int[][] arr4=new int[3][];

2.2、如何调用数组的指定位置的元素

//二维数组的声明和初始化
		int[][] arr2=new int[][]{{1,2,3},{2,1,9,2},{4,32,74}};

		//如何调用数组的指定位置的元素?
		//输出第二个数组的第三个元素9
		System.out.println(arr2[1][2]);//输出9
//	二维数组的动态初始化01:
		//说明该二维数组存了3个数组,其中每一数组里面存放2个元素
		int[][] arr3=new int[3][2];
		//如何调用数组的指定位置的元素?
		//输出第一个数组的第一个元素
		System.out.println(arr3[0][0]);//输出0
		
		arr3[0][0]=66;//给该位置赋值
		System.out.println(arr3[0][0]);//输出66

2.3、如何获取数组的长度

//二维数组的声明和初始化
		int[][] arr2=new int[][]{{1,2,3},{2,1,9,2},{4,32,74}};

		//获取数组的长度
		System.out.println("数组长度为:"+arr2.length);//数组长度为:3

2.4、如何遍历数组元素

//二维数组的声明和初始化
		int[][] arr2=new int[][]{{1,2,3},{2,1,9,2},{4,32,74}};
		//如何遍历数组?
		for (int i = 0; i < arr2.length; i++) {
			for (int j = 0; j < arr2[i].length; j++) {
				System.out.print(arr2[i][j]+" ");//1 2 3 2 1 9 2 4 32 74
			}
		}

2.5、数组元素的默认初始化值

int[][] arr5=new int[3][2];
		System.out.println(arr5[0]);//[I@15db9742  是一个堆空间的地址值  
		//[I@15db9742 
		//【:一个中括号说明是一维数组   I:说明是int类型  @+地址
		System.out.println(arr5[0][0]);//0
		String[][] arr6=new String[3][2];
		System.out.println(arr6[0]);//[Ljava.lang.String;@6d06d69c
		//[Ljava.lang.String;@6d06d69c
		//一维数组  String类型 @+堆空间地址
		System.out.println(arr6);//[[Ljava.lang.String;@7852e922
		//[[Ljava.lang.String;@7852e922
		//2个【:说明是二维数组  String类似;+堆空间地址

2.5、总结:

Java基础——3、数组(下)——二维数组_第1张图片

2.6、二维数组的内存解析

1、
放在方法里面的都叫局部变量——放在栈
new 出来的都——放在堆
局部变量arr1先放在栈 在栈空间中声明
后面new的部分会在堆里面声明,首地址值为【0x1234】
栈空间通过这个地址值找到堆空间里面数组的实体结构
从栈再到堆,一开始数组默认数据为null、null、null、null
2、
找到栈空间arr1的第二个数组 通过这个地址值找到堆空间里面的 数组的实体结构
3、
在堆空间生成0x7788的数组,赋值为1,2,3
4、
通过栈空间找到arr1的地址值,找到堆空间的第三个数组 堆空间里面再生成0x6677的数组
0x6677数组的第二个元素赋值为30,

5、
最终方法执行完毕之后,意味着它里面的局部变量没有用了
相继的栈空间里面的arr1会出栈
然后对应的指针就没有了
随后对应的【0x1234】被视为垃圾 最终出栈回收
对应的【0x7788】【0x6677】的指针没有了
对应堆空间里面的【0x7788】【0x6677】会被视为垃圾
最终释放堆空间和栈空间
实现垃圾回收
Java基础——3、数组(下)——二维数组_第2张图片

2.6、二维数组练习

Java基础——3、数组(下)——二维数组_第3张图片

public static void main(String[] args) {
		int[][] arr = new int[][]{{3,5,8},{12,9},{7,0,6,4}};
		int sum = 0;//记录总和
		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j < arr[i].length; j++) {
				sum += arr[i][j];
			}
		}
		System.out.println("总和为:"+sum);//总和为:54

	}

3、数组涉及到的算法:

定义一个int型的一维数组,包含10个元素,分别赋一些随机整数,
然后求出所有元素的最大值,最小值,和值,平均值,并输出出来。
要求:所有随机数都是两位数

  • 提示:
    random()获取的是一个double类型的值,需要强转
    【0,1)* 90 >>> 【0,90)+10 >>> 【10,100) >>> 【10,99】
    (int)(Math.random()*90+10)

3.1、求数组元素的最大值

public static void main(String[] args) {
		int[] arr = new int[10];
		for (int i = 0; i < arr.length; i++) {
			arr[i] = (int) (Math.random()*90+10);
			System.out.print("产生的随机数:"+arr[i]+" ");
		}
		System.out.println(" ");
		//求数组元素的最大值
		int max = arr[0];
		for (int i = 1; i < arr.length; i++) {
			if (max<arr[i]) {
				max=arr[i];
			}
		}
		System.out.println("最大值为:"+max);

	}

3.2、求数组元素的最小值

public static void main(String[] args) {
		int[] arr = new int[10];
		for (int i = 0; i < arr.length; i++) {
			arr[i] = (int) (Math.random()*90+10);
			System.out.print("产生的随机数:"+arr[i]+"\t");
		}
		System.out.println(" ");
		//求数组元素的最小值
		int min = arr[0];
		for (int i = 1; i < arr.length; i++) {
			if (min>arr[i]) {
				min=arr[i];
			}
		}
		System.out.println("最小值为:"+min);

	}

3.3、求数组元素的总和

public static void main(String[] args) {
		int[] arr = new int[10];
		for (int i = 0; i < arr.length; i++) {
			arr[i] = (int) (Math.random()*90+10);
			System.out.print("产生的随机数:"+arr[i]+"\t");
		}
		System.out.println(" ");
		//求数组元素的总和
		int sum = 0;
		for (int i = 1; i < arr.length; i++) {
			sum+=arr[i];
		}
		System.out.println("总和为:"+sum);

	}

3.4、数组的复制(赋值array2变量等于array1)

使用简单数组
(1)创建一 个名为ArrayTest的类,在main()方法中声明array1和array2两个变量, 他们是int[]类型的数组。
(2)使用大括号{},把array1初始化为8个素数: 2,3,5,7,11,13,17,19.
(3 )显示array1的内容。
(4 )赋值array2变量等于array1,修改array2中的偶索引元素,使其等于索引值(如array[0]=0 , array[2]=2)。打印出array1
【思考】: array1和array2是什么关系?
【解答】:array1和array2的地址值相同,都指向了堆空间的唯一的一个数组实体
【拓展】如何真正实现array2对array1数组的复制

public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] array1=new int[]{2,3,5,7,11,13,17,19};
		int[] array2;
		//1、遍历显示array1的内容
		for (int i = 0; i < array1.length; i++) {
			System.out.print(array1[i]+"\t");
		}
		System.out.println();
		
		//2、赋值array2变量等于array1
		array2=array1;
		//遍历显示array2
		for (int i = 0; i < array2.length; i++) {
			System.out.print("array2的数据"+array2[i]+"\t");
		}
		System.out.println();
		
		//3、修改array2中的偶索引元素,
		//使其等于索引值(如array[0]=0 , array[2]=2)
		for (int i = 0; i < array2.length; i++) {
			if (i%2==0) {
				array2[i]=i;
			}
		}
		//4.1、遍历显示新的array2的元素
		for (int i = 0; i < array2.length; i++) {
			System.out.print("array2的数据"+array2[i]+"\t");
		}
		System.out.println();//换行
		//4.2、再次遍历显示array1的元素
		for (int i = 0; i < array1.length; i++) {
			System.out.print("array1的数据"+array1[i]+"\t");
		}		
	}

最终输出结果这里是引用

//看输出结果会发现,数组1和数组2的元素居然是一模一样的
//但是我们想要的操作只是想改变array2的元素,为什么array1的元素也会改变呢???
//思考???
//建议看3.4.1、内存解析分析

3.4.1、内存解析

只看到了一个new的 所以从堆空间的角度分析,只有一个数组结构
当把array1的值赋给array2 的时候,在栈空间相当于把1堆空间的地址值给了2
相当于1和2在堆空间的角度看,是同一个数组
所以改2的值的时候,相当于是在改1的值
Java基础——3、数组(下)——二维数组_第4张图片
这就是为什么看结果显示,只改了2的值,1的值也变了在这里插入图片描述

【思考】: array1和array2是什么关系?
【解答】:array1和array2的地址值相同,都指向了堆空间的唯一的一个数组实体
【拓展】如何真正实现array2对array1数组的复制

3.4、数组的真正复制

针对上面的情况 改动部分代码  实现真正的复制
//2、赋值array2变量等于array1
		//array2=array1;错误写法
		//真正的数组复制:
		//正确写法
		array2=new int[array1.length];
		for (int i = 0; i < array2.length; i++) {
			array2[i] = array1[i];
		}
	完整的代码展示
public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] array1=new int[]{2,3,5,7,11,13,17,19};
		int[] array2;
		//1、遍历显示array1的内容
		for (int i = 0; i < array1.length; i++) {
			System.out.print(array1[i]+"\t");
		}
		System.out.println();
		
		//2、赋值array2变量等于array1
		//array2=array1;//错误写法
		//真正的数组复制:
		array2=new int[array1.length];
		for (int i = 0; i < array2.length; i++) {
			array2[i] = array1[i];
		}
		
		//3、修改array2中的偶索引元素,
		//使其等于索引值(如array[0]=0 , array[2]=2)
		for (int i = 0; i < array2.length; i++) {
			if (i%2==0) {
				array2[i]=i;
			}
		}
		//4.1、遍历显示新的array2的元素
		for (int i = 0; i < array2.length; i++) {
			System.out.print("array2的数据"+array2[i]+"\t");
		}
		System.out.println();//换行
		//4.2、再次遍历显示array1的元素
		for (int i = 0; i < array1.length; i++) {
			System.out.print("array1的数据"+array1[i]+"\t");
		}
				
	}
	

输出结果如下:
在这里插入图片描述
Java基础——3、数组(下)——二维数组_第5张图片

3.5、数组的反转

public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] array1=new int[]{2,3,5,7,11,13,17,19};
		//数组的反转 (元素颠倒)
		for (int i = 0; i < array1.length/2; i++) {
			int s1=array1[i];
			array1[i]=array1[array1.length-1-i];
			array1[array1.length-1-i]=s1;
		}
		//遍历输出查看反转后的结果、
		for (int i = 0; i < array1.length; i++) {
			System.out.print(array1[i]+"\t");
		}
		//控制台输出结果: 19	17	13	11	7	5	3	2			
	}

3.6、数组的查找

3.6.1、数组的线性查找

按照顺序一个一个查找,查找是否有匹配对应的元素

public static void main(String[] args) {
		//线性查找
		//找到该元素在数组里面的位置
		String[] arr = new String[]{"AA","BB","CC","DD","EE"};
		String search="CC";
		boolean flag = true;
		for (int i = 0; i < arr.length; i++) {
			if (search.equals(arr[i])) {
				System.out.println("找到了指定的元素,位置为:"+i);
				flag = false;
				break;
			}
		}
		if (flag) {
			System.out.println("该数组里面没有该元素");
		}
		
		//输出结果为:	"找到了指定的元素,位置为:2"
	}

3.6.2、数组的二分法查找

对半的划分范围,查找是否有匹配的元素
逐级对半划分范围,提高查找效率
Java基础——3、数组(下)——二维数组_第6张图片
以下是代码实现

public static void main(String[] args) {
		//二分法查找
		//前提:所要查找的数组必须有序   是从小到大排列的
		int[] arr1=new int[]{-12,-95,2,3,5,7,8,11,13,17,19,50};
		int search = 3;
		int head = 0;//首索引
		int end = arr1.length-1;//末索引
		boolean flag = true;
		while (head <= end) {
			int middle = (head+end)/2;
			if (search == arr1[middle]) {
				System.out.println("找到了指定的元素,位置为:"+middle);
				flag = false;
				break;
			}else if (arr1[middle] > search) {//从左边开始找
				end = middle - 1;
			}else {//arr1[middle] < search //从右边开始找
				head = middle + 1;
			}
					
		}
		if (flag) {
			System.out.println("该数组里面没有该元素");
		}
		//输出结果为:找到了指定的元素,位置为:3
	}

3.6.3、衡量排序算法的优劣:

1.时间复杂度: 分析关键字的比较次数和记录的移动次数——高效率
2.空间复杂度:分析排序算法中需要多少辅助内存 ——低存储
3.稳定性:若两个记录A和B的关键字值相等,但排序后A、B的先后次序保 持不变,则称这种排序算法是稳定的。

十大内部排序算法

前端十大经典排序算法.

选择排序
1、——直接选择排序
2、——堆排序******了解

交换排序
3、——冒泡排序*******重点了解
4、 ——快速排序*******重点了解

插入排序
5、 ——直接插入排序
6、——折半插入排序
7、——Shell排序(希尔排序)

8、归并排序******了解
9、桶式排序
10、基数排序

3.6.4、数组的排序算法

3.6.4.1、冒泡排序

介绍:
把数组元素按照从小到大的顺序排列
冒泡排序的原理非常简单,它重复地走访过要排序的数列,一次比较两个元
素,如果他们的顺序错误就把他们交换过来。

排序思想:
1.比较相邻的元素。如果第一个比第二个大(升序),就交换他们两个的位置。最终实现较大的元素逐渐从前面移向后面
2.依次对每一对相邻元素作同样的比对交换位置的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
3.针对所有的元素重复以上的步骤,除了最后一个。
4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要 比较为止。

如果是8个元素作比较
执行7大轮的比对 ——(外循环控制)
第一大轮相邻元素的比对,要执行7次 ——(内循环控制)
第二大轮相邻元素的比对,要执行6次
第三大轮相邻元素的比对,要执行5次
以后的执行次数都 -1

执行结果:在这里插入图片描述
代码如下:

public static void main(String[] args) {
		//数组冒泡排序的实现
		int[] arr = new int[]{43,32,99,76,-98,0,64,33,-21,32};//无序的 有重复数据的数组
		//调整顺序
		for(int i = 0;i < arr.length - 1;i++){//外层控制大的轮次
			for (int j = 0; j < arr.length-1-i; j++) {//内层控制一轮比对的次数
				if (arr[j] > arr[j+1]) {//相邻元素两两对比
					int num = arr[j];//元素交换
					arr[j] = arr[j+1];
					arr[j+1] = num;
				}
			}
		}
		//遍历显示该数组元素
		System.out.println("输出顺序从小到大");
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i]+"\t");
		}
	}

冒泡排序 时间复杂度(n的平方)
Java基础——3、数组(下)——二维数组_第7张图片

4、Arrays工具类的使用

Java基础——3、数组(下)——二维数组_第8张图片

4.1、equals方法

public static void main(String[] args) {
		//boolean equals(int[] a,int[] b):判断两个数组是否相等。
		int[] arr = new int[]{1,2,3,4};
		int[] arr1 = new int[]{1,3,4,2};
		boolean isEquals = Arrays.equals(arr, arr1);
		System.out.println("两个数组是否相等:"+isEquals);//false
	}

分析equals源码Java基础——3、数组(下)——二维数组_第9张图片

4.2、toString方法

public static void main(String[] args) {
		//String toString(int[] a):输出数组信息
		int[] arr = new int[]{1,2,3,4};
		int[] arr1 = new int[]{1,3,4,2};
		System.out.println(Arrays.toString(arr));//[1, 2, 3, 4]
	}

分析toString源码:
Java基础——3、数组(下)——二维数组_第10张图片

4.3、fill方法

public static void main(String[] args) {
		//void fill(int[] a,int val):将指定值填充到数组之中
		int[] arr = new int[]{1,2,3,4};
		int[] arr1 = new int[]{1,3,4,2};
		Arrays.fill(arr1, 10);
		System.out.println(Arrays.toString(arr1));//[10, 10, 10, 10]
		
	}

分析fill源码:Java基础——3、数组(下)——二维数组_第11张图片

4.4、sort方法

public static void main(String[] args) {
		//void sort(int[] a):对数组进行排序。
		int[] arr = new int[]{1,2,3,4};
		int[] arr1 = new int[]{1,3,4,2};
		System.out.println(Arrays.toString(arr1));//[1, 3, 4, 2]
		Arrays.sort(arr1);//按照从小到大的顺序排序
		System.out.println(Arrays.toString(arr1));//[1, 2, 3, 4]
		
	}

分析sort源码:在这里插入图片描述

4.5、binarySearch查找方法

public static void main(String[] args) {
		//int binarySearch(int[] a,int key)
		int[] arr1 = new int[]{1,3,56,2,84,3};
		int index = Arrays.binarySearch(arr1,56);//找56这个元素在数组的位置
		System.out.println("56的索引:"+index);//2
		
	}

5、数组中的常见异常

5.1、数组角标越界异常

public static void main(String[] args) {
		//数组角标越界:ArrayIndexOutOfBoundsException
		int[] arr1 = new int[]{1,3,4,2};
		//错误的写法
		for (int i = 0; i <= arr1.length; i++) {
			System.out.println(arr1[i]);
		}
		//正确的写法 去掉 =
		for (int i = 0; i < arr1.length; i++) {
			System.out.println(arr1[i]);
		}
		
	}

Java基础——3、数组(下)——二维数组_第12张图片

5.2、空指针异常NullPointerException

情况一:

public static void main(String[] args) {
		//空指针异常 NullPointerException
		int[] arr1 = new int[]{1,3,4,2};
		arr1 = null;
		System.out.println(arr1[0]);
		
	}

Java基础——3、数组(下)——二维数组_第13张图片

情况二:

public static void main(String[] args) {
		//空指针异常 NullPointerException
		int[][] arr1 = new int[4][];//没有定义具体的元素
		System.out.println(arr1[0][0]);//所以会报空指针
	}

在这里插入图片描述

情况三:

Java基础——3、数组(下)——二维数组_第14张图片
数组完结

你可能感兴趣的:(JAVA基础,java,动态规划,数据结构)