2021-04-12

第六节 数组

数组的概念

一组连续的储存空间,存储多个相同数据类型的值

数组的特点

类型相同
长度固定

数组的组成

数组中每个数据格被称为“数组元素”。
对每个元素进行赋值或取值的操作被称为“元素的访问”。
访问元素时,需要用“下标”(从0开始,依次+1,自动生成)
访问语法:数组名[下标]:例如 存:a[0]=10,取:a[0];

数组的声明与赋值

声明int数组类型的变量,定义变量名为a
int [] a=new int[5];
需要在内存中找到长度为5的连续空间,来存储数组

下标范围

有效下标范围:0~数组长度-1
访问无效下标,会导致数组下标(索引)越界异常,java.lang.ArrayIndexOutOfBoundsException

数组的默认值

在没有为数组元素赋值的情况下,依旧可以正确访问,
数组默认值:整数:0,小数:0.0,字符:空格,布尔:false,其他:null

数组创建语法
先声明、再分配空间

数据类型[]数组名:
数组名=new 数据类型[长度];

声明并分配空间

数据类型[] 数组名=new 数据类型[长度];

声明并赋值(繁)

数据类型[] 数组名=new 数据类型[ ]{元素1,元素2,元素3,……};

声明并赋值(简)

数据类型[] 数组名={元素1,元素2,元素3,……}
//显式初始化,注意,不可换行。

数组的遍历

遍历:从头至尾,逐一对每个元素进行访问`
int[] a=new int [5];
for(int i=0;i<a.length;i++){
	System.out.print(a[i]+"\t")
	//用循环变量i充当下标,逐一访问每个元素。
}
System.out.println(a.lentgh);
//可获得数组元素长度

数组的扩容

创建数组时,必须指定数组长度,并在创建之后不可更改长度。

扩容思路

创建大于原数组长度的新数组
将原数组中的元素依次复制到新数组中

复制方式
循环将原数组中所有元素逐一赋值给新数组
int []arr=new int[]{11,22,33,44,55};

//1,逐一复制
//创建一个新数组arr1,确定数组长度
int [] arr1=new int[arr.lenght*2]
//用循环的方式将原数组中每一个元素复制给新数组,
for(int i=0;i<arr.length;i++){
	arr1[i]=arr[i]
}

//2,用System.arraycopy(原数组,原数组起始,新数组,新数组起始,复制长度)的方式直接复制
//创建一个新数组 
int[] arr2=new int[arr.length*2];
System.arraycopy(arr,0,arr2,0,arr.length);
//起始元素可以为任意值,复制长度也可以任意值,但要注意数组索引越界

//3,用数组工具,java.util.Arrays.copyOf(原数组,新数组长度),这个直接能生成一个数组返回。
java.util.Arrays.copyOf(arr,arr.length*2);
//这种的数组长度可以比原数组长或者短

//用forEach方式遍历每个元素,没有被赋值的元素用默认值
for(int i:arr1){
	System.out.print(i+"\n");
}
System.arraycopy(原数组,原数组起始,新数组,新数组起始,长度)
java.util.Arrays.copyOf(原数组,新长度);//返回带有原值的新数组。
地址的替换

数组作为引用类型之一,其变量中存储的是数组的地址。
完成元素复制后,需将新数组地址,赋值给原变量进行替换。
arr 0x00001001 11 22 33 44 55
arr 0x00001002 11 22 33 44 55 0 0 0 0 0
栈内存中存储的是对象的地址,堆内存中存储的是数组元素
如果是二维数组,堆内存中存储的是一维数组的地址,地址又指向堆内存中的数组元素

数组类型的参数和返回值
public class TestArray{
	public static void main(String[] args){
		int[] nums={11,22,33,44};
		printArray(nums);
		System.out.println("===============================");
		printArray(expand(nums));
	}
//数组类型的参数
	public static void printArray(int[] arr){
		for(int i=0;i<arr.length;i++){
			System.out.print(arr[i]+"\t");
		}
		System.out.println();
	}
//数组类型的返回值
	public static int[] expand (int [] arr){
		return java.util.Arrays.copyOf(arr,arr.length*2);
	}
}

方法调用时:将nums中的地址赋值给arr,此时二者指向同一个数组。
传递参数时:基本数据类型传递的是变量中的值,引用数据类型传递的是变量中的地址。

可变长参数

概念:可接收多个同类型实参,个数不限,使用方式与数组相同。
语法:数据类型…形参名//必须定义在形参列表的最后,且只能有一个

public class TestVarialbeMethod3 {
	public static void main(String[] args) {
		printHobby("张三");//i have no hobby
		printHobby("张三","playchanse");
		printHobby("张三","playbasketball","watchtv","music");
		//i like playbasketball watchtv music 
	}
	public static void printHobby(String name,String ...hobbys) {
		if(hobbys.length==0) {
			System.out.println("i have no hobby");
			return;
		}
		String  str="i like ";
//这个后面要有个空格 这样才能让后面出来的空开,不至于连在一起
		for (String h : hobbys) {
			str +=(h+" ");//str=str+h+" "
		}
		System.out.println(str);
	}
}

数组的排序

冒泡排序:相邻两个数值比较大小,互换位置

规律:外层循环length-1,内层循环length-1-i;

int [] arr=new int[]{11,22,33,44,55};
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 temp=arr[j];
			arr[j]=arr[j+1];
			arr[j+1]=temp;
		}
	}
}
选择排序:固定值与其他值依次比较大小,互换位置
int [] arr=new int[]{11,22,33,44,55};
for(int i=0;i<arr.length;i++){
	for(int j=i+1;j<arr.length;j++){
		if(arr[j]<arr[i]){//升序
			int temp=arr[j];
			arr[j]=arr[i];
			arr[i]=temp;
		}
	}
}
java.util.Arrays.sort(arr);
//自动执行了升序操作。这是一个没有返回值的方法
jkd排序:java.util.Arrays.sort(数组名);jdk提供的(升序)

数组的应用

二维数组

概念:一维数组中的一维数组;数组中的元素还是数组
二维数组相当于一个多行多列的表格
int [][]arr=new int[5][3];

二维数组的赋值

arr[0][0]=10;
arr[4][2]=20;
使用双下标访问二维数组中的元素
第一个下标代表行,高维下标
第二个下标代表列:低维下标

二维数组的内存分配

高维数组中的每一个元素,保存了低维数组的地址,访问arr[0]等价于在访问二维数组内元素一维数组的地址。

二维数组的遍历及访问
int[][]arr=new int[3][];
//不规则二维数组,低维数组长度不写必须要赋值,不然报数组索引越界异常
	arr[0]=new int[3];
	arr[0][0]=1; arr[0][1]=2; arr[0][2]=3;
	arr[1]=new int[2];
	arr[1][0]=4; arr[1][1]=5; 
	arr[2]=new int[4];
	arr[2][0]=7; arr[2][1]=8; arr[2][2]=9;arr[2][3]=10;			
int[][]arrs=new int[3][];
	arrs[0]=new int[] {1,33,54,5,};
	arrs[1]=new int[] {1,3,44,5,19,3};
	arrs[2]=new int[] {1,23,4,};
	arrs[3]=new int[] {1,31,44,95,19,11};		
	System.out.println("用for循环来遍历数组");
for(int i=0;i<arr.length;i++){
	for(int j=0;j<arr[i].length;j++){
		System.out.print(arr[i][j]+"\t");
	}
	System.out.println();
}
System.out.println("用forEach来遍历数组,");
for(int[] A:arr){
	for(int a:A) {
		System.out.print(a+"\t");
	}
	System.out.println();
}
二维数组打印杨辉三角
/*
 *        1
 *       1 1
 *      1 2 1
 *     1 3 3 1
 *    1 4 6 4 1
 *   1 5 10 10 5 1
 */
package array4_4;
import java.util.Scanner;
public class TestYHSJ {
	static Scanner input=new Scanner(System.in);
	public static void main(String[] args) {
		System.out.println("请输入一个行数");
		int row=input.nextInt();
	//	print(jisuan(fuzhi(ewsz(row))));
		printYHSJ(jisuan(fuzhi(ewsz(row))));
	}	
//创建不同长度的二维数组。
	public static int[][] ewsz(int row) {
		int [][]ewsz=new int[row][];
		for(int i=0;i<row;i++) {
			ewsz[i]=new int[i+1];
		}
		return ewsz;
	}
//二维数组的赋值	
	public static int[][] fuzhi(int[][] ewsz) {
		for(int i=0;i<ewsz.length;i++) {
			ewsz[i][0]=1;
			ewsz[i][i]=1;
		}
		return ewsz;
	}	
//二维数组的中间赋值
	public static int[][] jisuan(int[][] ewsz) {
		
		for(int i=2;i<ewsz.length;i++) {
			for(int j=1;j<i/*ewsz[i].length-1*/;j++) {
				ewsz[i][j]=ewsz[i-1][j-1]+ewsz[i-1][j];
			}
		}
		return ewsz;
	}	
//杨辉三角的打印
	public static void printYHSJ(int[][] arr) {
		for(int i=0;i<arr.length;i++) {
			
			for(int j=arr.length-1;j>i;j--) {
				System.out.print("\t");
			}
			
			for(int j=0;j<arr[i].length;j++) {
				System.out.print("\t"+arr[i][j]+"\t");
			}
			System.out.println();
		}
	}
//打印二维数组		
	public static void print(int[][]arr) {
		for(int i=0;i<arr.length;i++) {
			for(int j=0;j<arr[i].length;j++) {
				System.out.print(arr[i][j]+"\t");
			}
			System.out.println();
		}
	}
}

数组工具
import java.util.Arrays;

public class ArrayTool2 {
	public static void main(String[] args) {
		double[] arr3 = { 1, 2, 3, 4 };
		double[] arr4 = { 1, 2, 3, 4 };
		boolean isEquals2 = Arrays.equals(arr3, arr4);
		System.out.println(isEquals2);//true
		System.out.println(arr3==arr4);//false
//==比较的是地址,equals比较的是数组的内容
		
		Arrays.fill(arr4 ,2.0);
		//把数组arr4中所有元素填充为2.0
		print(arr4);//2.0	2.0	2.0	2.0	
		
		Arrays.fill(arr3,1,4,10 );
		//把数组中指定索引的元素修改为10
		print(arr3);//1.0	10.0	10.0	10.0
		
		
		double[][] arr1 = { { 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11, 12 }, { 13, 14, 15, 16, 17 }, };
		double[][] arr2 = { { 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11, 12 }, { 13, 14, 15, 16, 17 }, };

		boolean isEquals3 = Arrays.equals(arr1, arr2);
		System.out.println(isEquals3);//false
		System.out.println(arr1==arr2);//false
		
		boolean isEquals = Arrays.equals(arr1[0], arr2[0]);
		System.out.println(isEquals);//true
		System.out.println(arr1[0]==arr2[0]);//false
	}
	private static void print(double[] arr4) {
		for(double a:arr4) {
			System.out.print(a+"\t");
		}
		System.out.println();
	}
	public static void print(int[][] arr) {
		for (int[] array1 : arr) {
			for (int array2 : array1) {
				System.out.print(array2 + "\t");
			}
			System.out.println("内层循环结束");
		}
		System.out.println("外层循环结束");
	}
}
数组随机数练习
/*
 * 打印75-100之间的所有数,包含在数组中
 */
import java.util.Arrays;
import java.util.Random;

public class SuiJIShu {
	public static void main(String[] args) {
		Random r=new Random();
		int[]arr=new int[10];
		for(int i=0;i<10;i++) {
			if(i<arr.length/2){
				arr[i]=(r.nextInt(26)+75);
		//括号里面写了26,就是0到26之间的整数,都是包左不包右
			}else {
				arr[i]=(int)(Math.random()*26+75);
		//Math.random()括号里面不能写东西,只能乘*26.
			}
			System.out.println(arr[i]);
		}
		for(int i:arr) {
			System.out.print(i+"\t");
		}	
		System.out.println("\n===============");
		System.out.println(arr.toString());
		System.out.println(Arrays.toString(arr));
	}
}
数组算全班同学成绩
import java.util.Scanner;
public class OneStudent {
	public static void main(String[] args) {
		Scanner input=new Scanner(System.in);
		System.out.println("请输入班级学生个数");
		int nums=input.nextInt();
		double sum=0.0;
		double[] arr=new double[nums];
		for(int i=0;i<arr.length;i++) {
			System.out.println("请输入班级学生成绩");
			arr[i]=input.nextDouble();
			sum+=arr[i];
		}
		System.out.println("全班同学总成绩为:"+sum);
		System.out.println("全班同学平均成绩为:"+sum/nums);		
	}
}
数组打印俄罗斯方块
package Arrays;

import java.util.Random;

public class GameArraysLS2 {

	public static void main(String[] args) {
//		printShape(null);
		printShape2(getRandomShape());
	}
		public static void printShape(int[][] shapes) {
		for(int i=0;i<4;i++) {
			for (int j = 0; j < 4; j++) {
				System.out.print("□ ");
			}
			System.out.println();
		}
	}
	
	/*
	 * 打印随机生成的表示二维数组的形状
	 * shapes 表示俄罗斯方块形状的二维数组
	 * 看他的坐标在不在4*4的框里面。
	 */
	public static void printShape2(int[][] shapes) {
		//在44*4的区域来绘制俄罗斯方块,为什么是4*4,因为里面有7中情况,任何一个俄罗斯方块可以在这个范围内显示
		for(int i=0;i<4;i++) {
			for (int j = 0; j < 4; j++) {
				boolean flag=false;
				for (int k = 0; k < 4; k++) {
					if(shapes[k][0]==i&&shapes[k][1]==j) {
						flag=true;
						break;
					}
				}
				//判断给定的点的坐标x=i,y=j每个形状4个点。一个表示俄罗斯方块的二维数组。
				if(!flag) {//这里的flag是判断的,flag为true的时候打印实心,flag为false
					System.out.print("□ ");
				}else {
					System.out.print("■ ");
				}				
			}
			System.out.print("\n");
		}
		System.out.println();
	}	
	/*
	 * 借助随机数来生成一个表示俄罗斯方块的二维数组
	 */
	public static int[][] getRandomShape() {
		//得到一个随机的表示俄罗斯方块的二维数组。
		Random r = new Random();
		
		int shape = r.nextInt(7);
		int type = r.nextInt(4);
		
		int[][] shapes = new int[4][2];
		
		switch (shape) {
		case 0:	//	方块
			shapes = new int[][]{{0, 0}, {0, 1}, {1, 0}, {1, 1}};
			break;			
		case 1:	//	长条
			switch (type) {
			case 0:
			case 2:		//	横条
				shapes = new int[][]{{0, 0}, {0, 1}, {0, 2}, {0, 3}};
				break;

			default:	//	数条
				shapes = new int[][]{{0, 0}, {1, 0}, {2, 0}, {3, 0}};
				break;
			}
			break;
		case 2:	//	T
			switch (type) {
			case 0:	//	T
				shapes = new int[][]{{0, 0}, {0, 1}, {0, 2}, {1, 1}};
				break;
			case 1:	//	-|
				shapes = new int[][]{{0, 1}, {1, 0}, {1, 1}, {2, 1}};
				break;
			case 2:	//	土
				shapes = new int[][]{{0, 1}, {1, 0}, {1, 1}, {1, 2}};
				break;
			default://	|-
				shapes = new int[][]{{0, 0}, {1, 0}, {2, 0}, {1, 1}};
				break;
			}
			break;
		case 3://L形状
			switch(type) {
			case 0:
				shapes=new int[][] {{0,0},{1,0},{2,0},{2,1}};
				break;
			case 1:
				shapes=new int[][] {{0,0},{1,0},{0,1},{0,2}};
				break;
			case 2:
				shapes=new int[][] {{0,0},{0,1},{1,1},{2,1}};
				break;
			default :
				shapes=new int[][] {{0,2},{1,0},{1,1},{1,2}};
				break;
			}
			break;
		case 4://反L
			switch(type) {
			case 0:
				shapes=new int[][] {{0,0},{1,0},{2,0},{2,1}};
				break;
			case 1:
				shapes=new int[][] {{0,0},{0,1},{0,2},{1,2}};
				break;
			case 2:
				shapes=new int[][] {{0,1},{1,2},{2,0},{2,1}};
				break;
			default:
				shapes=new int[][] {{0,0},{1,0},{2,0},{2,1}};
				break;
			}break;
		case 5://Z
			switch(type) {
			case 0:
			case 2:
				shapes=new int[][] {{0,0},{0,1},{1,1},{1,2}};
				break;
			default:
				shapes=new int[][] {{0,1},{1,0},{1,1},{2,0}};
				break;
			}break;			
		case 6://反Z
			switch(type) {
			case 0:
			case 2:
				shapes=new int[][] {{1,0},{1,1},{0,1},{0,2}};
				break;
			default :
				shapes=new int[][] {{0,0},{1,0},{1,1},{2,1}};
				break;
			}
			break;
		}
		return shapes;
	}	
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值