Java 数组

数组

 含义:
 		存储同一种数据类型多个元素的固定容器
前提条件:
       1.数组一旦初始化,数组在内存中的长度固定不变
	   2.数组中的元素在内存中必须是同一种数据类型
       3.数组中的元素在内存中必须是多个,如果初始化可以存储0个元素和1个元素的数组
       	也不会编译报错,只不过这样的数组没有任何意义

数组的声明

  含义:
       定义数组
   格式:
       数据类型[] 数组名;(推荐)
       数据类型 数组名[];
   解释:
       数据类型:数组中元素的数据类型
       []:定义的是数组
       数据类型[]:数组的数据类型
       数组名:数组的名字

数组的初始化

   分类:
       动态初始化
           在初始化数组时,只会初始化数组的大小(长度),不会初始化数组中具体存储的元素,JVM可以直接获取到数组的长度
       静态初始化
           在初始化数组时,不会初始化数组的大小(长度),只会初始化数组中具体存储的元素,JVM可以间接获取到数组的长度
   格式:
       动态初始化:
           数据类型[] 数组名 = new 数据类型[长度];
       静态初始化:
           标准版:
               数据类型[] 数组名 = new 数据类型[]{元素1,元素2,......,元素n};
           简化版:
               数据类型[] 数组名 = {元素1,元素2,......,元素n};
               备注:JVM会根据数组名前面的数据类型[]隐式填充new 数据类型[]
   解释:
       new:向JVM内存申请并开辟内存空间
       数据类型:数组中元素的数据类型
       长度:数组的大小
		//动态初始化
		int[] arr01 = new int[3];
		//静态初始化(标准版)
		int[] arr02 = new int[]{11,22,33};
		//静态初始化(简化版)
		int[] arr03 = {11,22,33};
数组声明初始化的注意事项:
    1.数组中元素支持类型的转换
    2.数组不支持动静结合的方式进行数组的初始化
    3.进行数组的动态初始化时,数组的长度只能是正整数(长度为0的数组没有任何意义)
    4.数组静态初始化的简化版不可以先声明后初始化;
        原因:数组静态初始化的标准版会根据数组名前面的数据类型[]隐式填充"new 数据类型[]",数组静态初始化的简化版
        先声明后初始化时无法直接获取数组名前面的数据类型
		int[] arr01 = {11,22,33,'a'};
		int[] arr02 = {11,22,33,(int)3.14};
		
		//int[] arr03 = new int[3]{11,22,33};//错误
		//int[] arr04 = new int[-3];//数组初始化异常

		int[] arr05;
		arr05 = new int[3];

		int[] arr06;
		arr06 = new int[]{11,22,33};
		
		int[] arr07;
		//arr07 = {11,22,33};错误

数组的访问

分类:
       获取数组中指定元素
       获取数组中元素个数

获取数组中指定元素
   如果访问数组中的元素必须通过数组的索引值进行获取和访问

索引值:
   含义:
       JVM针对数组中的元素进行动态的数字编号
   特点:
       1.长度为0的数组不存在索引值
       2.索引值从0开始,依次类推,最大的索引值为数组的长度-1
   格式:
       赋值格式:
           数组名[索引值] = 元素值;
       获取格式:
           数组名[索引值]
   注意:
       进行数组元素的赋值和获取时,索引值如果非法或不存在,编译不会报错,但是在
       运行时进行访问或获取的时候,发生
       ArrayIndexOutOfBoundsException(数组索引越界异常)
		//声明并初始化数组
		int[] arr = {11,22,33};

		System.out.println(arr);
		//[I@1b6d3586,这个东西就是数组值(地址值,并非内存地址值,内存地址值是物理地址,
		// 地址值是人工模拟的内存地址值)

		System.out.println(arr[0]);
		System.out.println(arr[1]);
		System.out.println(arr[2]);
		System.out.println(arr[3]);
获取数组中元素个数
   格式:
       数组名.length
		//声明初始化数组																																																													
		int[] arr = {11,22,33};

		System.out.println(arr[0]);
		System.out.println(arr[1]);
		System.out.println(arr[2]);

		System.out.println("=========================");

		for (int i = 0; i < 3; i++) {
			System.out.println(arr[i]);
		}
		System.out.println("=========================");

		for (int i = 0; i < arr.length; i++) {
			System.out.println(arr[i]);
		}

数组的应用

   基础应用:
       不改变数组中元素位置的基础上,进行查询操作
       例如:
           求和,求最值,......
   高级应用
       针对数组中元素的索引位置进行改变,进行所需的操作
       例如:
           反转,排序
   综合应用
       在数组的操作的基础上加入方法或其它知识点,进行综合操作
       例如:
           二分查找,动态操作,......
按照固定的格式拼接数组中的元素
  固定格式:
       数组:[元素1, 元素2, ......,元素n]
       
       //创建数组
		int[] arr = {11,22,33,44,55};
		System.out.print("数组:[");
		//遍历数组
		for (int i = 0; i < arr.length; i++) {
			//判断是否为最后一个元素
			if (i == arr.length - 1) {
				System.out.println(arr[i] + "]");
			} else {
				System.out.print(arr[i] + ", ");
			}
		}

获取数组中所有元素的累加和

		//创建数组
		int[] arr = {11,22,33};
		//声明并初始化求和变量
		int sum = 0;
		//遍历数组
		for (int i = 0; i < arr.length; i++) {
			sum += arr[i];
		}
		//打印求和变量
		System.out.println("sum = " + sum);

获取数组中所有元素的最大值

		//声明并初始化数组
		int[] arr = {5,15,2000,10000,100,4000};
		//声明并初始化最大值变量
		int max = arr[0];
		//遍历数组
		for (int i = 1; i < arr.length; i++) {
			//进行比较
			if (max < arr[i]) {
				max = arr[i];
			}
		}
		//打印最大值变量
		System.out.println("max = " + max);

分析以下需求,并用代码实现:
(1)在编程竞赛中,有10位评委为参赛的选手打分,分数分别为:5,4,6,8,9,0,1,2,7,3
(2)求选手的最后得分(去掉一个最高分和一个最低分后其余8位评委打分的平均值)

		//声明并初始化数组保存评委分数
		int[] arr = {5,4,6,8,9,0,1,2,7,3};
		//获取10位评委的总分
		//获取10位评委的最高分
		//获取10位评委的最低分
		int sum = arr[0];
		int max = arr[0];
		int min = arr[0];
		//遍历数组
		for (int i = 1; i < arr.length; i++) {
			sum += arr[i];
			if (max < arr[i]) {
				max = arr[i];
			}
			if (min > arr[i]) {
				min = arr[i];
			}
		}
		//获取选手最后得分
		double avg = (sum - max - min) * 1.0 / (arr.length - 2);
		System.out.println("avg = " + avg);

获取指定元素在数组中出现的第一次索引

		//声明并初始化数组
		int[] arr = {11,22,33,44,55,22,45,22,54,22};
		//声明并初始化索引
		int index = -1;
		//声明并初始化指定元素
		int num = 22;

		//遍历数组
		for (int i = 0; i < arr.length; i++) {
			if (num == arr[i]) {
				index = i;
				break;
			}
		}
		//打印索引
		if (index == -1) {
			System.out.println("指定元素在数组中没有出现......");
		} else {
			System.out.println("指定元素在数组中出现的第一次索引是:" + index);
		}

数组的反转

   将数组首尾对应的元素进行索引位置的互换
   反转前:[11, 22, 33, 44, 55]
   反转后:[55, 44, 33, 22, 11]

  分析:
   1.首次进行首尾互换元素的索引位置
       int i = 0;
       int j = arr.length - 1;
   2.首尾互换元素索引位置操作的规律
       i++,j--
   3.如何进行元素的互换
       int temp = arr[i];
       arr[i] = arr[j];
       arr[j] = temp;
   4.互换元素的前提条件?
        如果数组长度为奇数个时: i < j
        如果数组长度为偶数个时: i < j
		//声明并初始化数组
		int[] arr = {11,22,33,44,55};

		System.out.print("反转前:[");
		for (int i = 0; i < arr.length; i++) {
			if (i == arr.length - 1) {
				System.out.println(arr[i] + "]");
			} else {
				System.out.print(arr[i] + ", ");
			}
		}

		//反转操作
		for (int i = 0 , j = arr.length - 1 ; i < j ; i++ , j--) {
			int temp = arr[i];
			arr[i] = arr[j];
			arr[j] = temp;
		}


		System.out.print("反转后:[");
		for (int i = 0; i < arr.length; i++) {
			if (i == arr.length - 1) {
				System.out.println(arr[i] + "]");
			} else {
				System.out.print(arr[i] + ", ");
			}
		}

优化

	5.i和j的关系:
       i + j = arr.length - 1;
           j = arr.length - 1 - i;
   6.优化i < arr.length - 1 - i
       i + i  < arr.length - 1
        2 * i < arr.length - 1
           i < arr.length/2 - 1/2
           i < arr.length/2
		//反转操作
		for (int i = 0; i < arr.length/2 ; i++) {
			int temp = arr[i];
			arr[i] = arr[arr.length - 1 - i];
			arr[arr.length - 1 - i] = temp;
		}

数组的排序

按照某种排序规则让数组中元素从小到大或从大到小依次排列

排序算法分类:
   冒泡排序
   选择排序
   希尔排序
   归并排序
   快速排序
   插入排序
   ......

冒泡排序:求最大值排序

 分析:
       原理:将相邻两个整数进行比较,将较大值移动到右侧
       考虑到一次循环无法获取排序后的数组,需要使用循环嵌套
           外层循环变量:求最大值的次数
       	   内层循环变量:求一次最大值需要比较的次数
		//排序操作
		//外层循环变量:求最大值的次数
		for (int count = 1; count < arr.length ; count++) {
			//内层循环变量:求一次最大值需要比较的次数
			/*
				数组长度为6,需要进行5次求最大值
					第1次交换最大值至最右侧,比较的循环次数为5(6 - 1)
					第2次交换最大值至剩余元素最右侧,比较的循环次数为4(6 - 2)
					第3次交换最大值至剩余元素最右侧,比较的循环次数为3(6 - 3)
					第4次交换最大值至剩余元素最右侧,比较的循环次数为2(6 - 4)
					第5次交换最大值至剩余元素最右侧,比较的循环次数为1(6 - 5)
			*/
			for (int i = 0; i < arr.length - count; i++) {
				if (arr[i] > arr[i+1]) {
					int temp = arr[i];
					arr[i] = arr[i+1];
					arr[i+1] = temp;
				}
			}
		}
优化
		//排序操作
		//外层循环变量:求最大值的次数
		for (int count = 1; count < arr.length; count++) {
			//声明并初始化临时最大值索引(获取最大值存储的索引位置)
			int index = arr.length - count;
			/*
				数组长度为6,需要进行5次求最大值
					第1次比较最大值是否在index处,比较的循环次数为5(6 - 1)
					第2次比较剩余数据最大值是否在index处,比较的循环次数为4(6 - 2)
					第3次比较剩余数据最大值是否在index处,比较的循环次数为3(6 - 3)
					第4次比较剩余数据最大值是否在index处,比较的循环次数为2(6 - 4)
					第5次比较剩余数据最大值是否在index处,比较的循环次数为1(6 - 5)
			*/
			for (int i = 0; i < arr.length - count; i++) {
				System.out.println(arr[index] + "<" + arr[i]);

				if (arr[index] < arr[i]) {
					index = i;
				}
			}

			System.out.println("===========");

			//进行元素位置的互换
			if (index != arr.length - count) {
				int temp = arr[arr.length - count];
				arr[arr.length - count] = arr[index];
				arr[index] = temp;
			}
		}
数组和方法使用时的健壮性判断:
   1.当方法的形式是引用类型时,需要在方法内部针对该参数进行非空校验,如果使用null调用任何内容,会发生空指针异常NullPointerException
   2.除了引用类型还需要根据实际需求判断方法其它的实参
		int[] arr = {11,22,33,44,55};
		int num = getNum(arr,9);
		System.out.println(num);
		
		public static int getNum (int[] arr , int index) {
			//非空校验
			if (arr == null) {
				return 0;
			}
			//数组非法索引判断
			if (index < 0 || index >= arr.length) {
				return 0;
			}
			int num = arr[index];
			return num;
		}
方法传递参数时的特点:
   当方法的形参是基本类型时:
       1.参数传递的内容是该基本类型的数据值
       2.形式参数数据值的改变不会影响实际参数的数据值
   当方法的形参是引用类型时:
       1.参数传递的内容是该引用类型的地址值
       2.形式参数地址值的改变不会影响实际参数的地址值
       3.形式参数地址值不变,形式参数地址值中内容的改变影响实际参数地址值中内容

可变参数(JDK5.0)

   含义:
       调用方法时传递实参可以任何个数的形参(其实就是一个根据实参内容进行静态初始化的数组)
   好处:
       简化部分情况下的重载
   位置:
       方法的形参列表中
   格式:
       数据类型... 可变参数名
	public static void main(String[] args) {
		method(11,22,33,44,55,66,77,88);
	}

	public static void method (int... a) {
		System.out.println(a);//[I@1b6d3586
		System.out.println(a.length);
		System.out.println(a[0]);
	}

可变参数的注意事项:
1.当方法的形参列表中除了可变参数外还存在其它参数,需要将可变参数写在形参列表的最后
2.方法的形参列表中最多只能含有一个可变参数

	public static void main(String[] args) {
		method("HelloWorld",11,22,33,44,55);
	}

	public static void method (String str , int... arr) {}
获取指定元素在数组中出现的第一次索引
二分查找法(折半查找法)
   前提条件:待操作的数组必须是元素大小有序的数组
		public static void main(String[] args) {
		//声明并初始化数组
		int[] arr = {2,5,7,8,10,15,18,20,22,25,28};//数组必须是有序的
		//声明并初始化指定元素
		int num = 18;

		int index = getIndex(arr, num);

		//打印索引
		if (index == -1) {
			System.out.println("指定元素在数组中没有出现......");
		} else {
			System.out.println("指定元素在数组中出现的第一次索引是:" + index);
		}
	}

	public static int getIndex(int[] arr, int num) {
		//声明并初始化索引变量
		int index = -1;

		//进行数组的非空校验
		if (arr == null) {
			return index;
		}

		//声明并初始化指定的索引范围变量
		int start = 0;
		int end = arr.length - 1;
		//声明并初始化中间索引位置变量
		int mid = (start + end)/2;

		//考虑到不太清楚循环次数,选择while循环
		while (start <= end) {
			if (arr[mid] < num) {
				start = mid + 1;
				//mid = (start + end) / 2;
			} else if (arr[mid] > num) {
				end = mid - 1;
				//mid = (start + end) / 2;
			} else {
				index = mid;
				break;
			}

			mid = (start + end) / 2;
		}

		return index;
	}
数组的动态操作:
   数组的动态扩容:
       创建新数组,进行数组的复制将待添加的元素存储到新数组中的最后
   数组的动态插入:
       创建新数组,根据指定的索引位置将待添加的元素存储到该新数组中
   数组的动态删除:
       创建新数组,根据指定的索引位置复制数组中的元素

数组的动态扩容

	public static void main(String[] args) {
		//声明并初始化数组
		int[] arr = {11,22,33,44,55};
		//声明并初始化待添加元素
		int num = 66;
		System.out.println("数组动态扩容前:");
		print(arr);
		//进行动态扩容
		arr = add(arr, num);
		System.out.println("数组动态扩容后:");
		print(arr);
	}
	/*
		动态扩容的两个明确:
			返回类型:int[]
			形参列表:int[] oldArr,int num
	*/
	public static int[] add (int[] oldArr , int num) {
		//非空校验
		if (oldArr == null) {
			return oldArr;
		}
		//根据原来的数组创建新数组
		int[] newArr = new int[oldArr.length + 1];
		//进行数据复制
		for (int i = 0; i < oldArr.length; i++) {
			newArr[i] = oldArr[i];
		}
		//将待添加元素存储到新数组的最后
		newArr[newArr.length - 1] = num;
		//返回新数组
		return newArr;
	}

	public static void print (int[] arr) {
		//非空校验
		if (arr == null) {
			return;
		}
		//特殊实参判断
		if (arr.length == 0) {
			System.out.println("[]");
			return;
		}

		System.out.print("[");
		for (int i = 0; i < arr.length; i++) {
			if (i == arr.length - 1) {
				System.out.println(arr[i] + "]");
			} else {
				System.out.print(arr[i] + ", ");
			}
		}
	}

数组的动态插入

	public static void main(String[] args) {
		//声明并初始化数组
		int[] arr = {11,22,33,44,55};
		//声明并初始化待插入元素
		int num = 66;
		System.out.println("数组动态插入前:");
		print(arr);
		//进行动态插入
		arr = insert(arr,num,1);
		System.out.println("数组动态插入后:");
		print(arr);
	}
	/*
		动态插入的两个明确:
			返回类型:int[]
			形参列表:int[] oldArr,int num,int index
	*/
	public static int[] insert (int[] oldArr,int num,int index) {
		//非空校验
		if (oldArr == null) {
			return oldArr;
		}
		//非法索引判断
		if (index < 0 || index >= oldArr.length) {
			return oldArr;
		}
		//根据原来的数组创建新数组
		int[] newArr = new int[oldArr.length + 1];
		//进行数据的复制
		for (int i = 0; i < oldArr.length; i++) {
			if (i < index) {
				newArr[i] = oldArr[i];
			} else {
				newArr[i+1] = oldArr[i];
			}
		}
		//将待插入元素存储到index位置上
		newArr[index] = num;
		return newArr;
	}
	public static void print (int[] arr) {
		//非空校验
		if (arr == null) {
			return;
		}
		//特殊实参判断
		if (arr.length == 0) {
			System.out.println("[]");
			return;
		}
		System.out.print("[");
		for (int i = 0; i < arr.length; i++) {
			if (i == arr.length - 1) {
				System.out.println(arr[i] + "]");
			} else {
				System.out.print(arr[i] + ", ");
			}
		}
	}

数组的动态删除

	public static void main(String[] args) {
		//声明并初始化数组
		int[] arr = {11,22,33,44,55};
		System.out.println("数组动态删除前:");
		print(arr);
		//进行动态删除
		arr = remove(arr,2);
		System.out.println("数组动态删除后:");
		print(arr);
	}
	/*
		动态删除的两个明确:
			返回类型:int[]
			形参列表:int[] oldArr,int index
	*/
	public static int[] remove (int[] oldArr,int index) {
		//非空校验
		if (oldArr == null) {
			return oldArr;
		}
		//非法索引判断
		if (index < 0 || index >= oldArr.length) {
			return oldArr;
		}
		//根据原来数组创建新数组
		int[] newArr = new int[oldArr.length - 1];
		//数组元素的复制
		for (int i = 0; i < newArr.length; i++) {
			if (i < index) {
				newArr[i] = oldArr[i];
			} else {
				newArr[i] = oldArr[i+1];
			}
		}
		//返回新数组
		return newArr;
	}

	public static void print (int[] arr) {
		//非空校验
		if (arr == null) {
			return;
		}
		//特殊实参判断
		if (arr.length == 0) {
			System.out.println("[]");
			return;
		}
		System.out.print("[");
		for (int i = 0; i < arr.length; i++) {
			if (i == arr.length - 1) {
				System.out.println(arr[i] + "]");
			} else {
				System.out.print(arr[i] + ", ");
			}
		}
	}

多维数组

   含义:
       数组中的元素依然是数组的数组
   分类:
       一维数组(我们之前学习的就是一维数组,多维数组中不包含一维数组)
       二维数组
       三维数组
       ......

二维数组的声明:
   数据类型[][] 数组名;(推荐)
   数据类型 数组名[][];
   数据类型[] 数组名[];
二维数组的初始化:
   动态初始化:
       格式1:初始化二维数组长度的同时,也初始化里面每个一维数组的长度
           数据类型[][] 数组名 = new 数据类型[x][y];
           x:二维数组的长度,也就是包含几个一维数组
           y:二维数组中每个一维数组的长度
       格式2:只初始化二维数组长度,但不会初始化里面每个一维数组的长度
           数据类型[][] 数组名 = new 数据类型[x][];
   静态初始化:
       格式1:
           数据类型[][] 数组名 = new 数据类型[][]{new 数据类型[]{元素1,元素2,......,元素n},new 数据类型[]{元素1,元素2,......,元素n},......,new 数据类型[]{元素1,元素2,......,元素n}}
       格式2:
           数据类型[][] 数组名 = {new 数据类型[]{元素1,元素2,......,元素n},new 数据类型[]{元素1,元素2,......,元素n},......,new 数据类型[]{元素1,元素2,......,元素n}}
       格式3:
           数据类型[][] 数组名 = new 数据类型[][]{{元素1,元素2,......,元素n},{元素1,元素2,......,元素n},......,{元素1,元素2,......,元素n}}
       格式4:
           数据类型[][] 数组名 = {{元素1,元素2,......,元素n},{元素1,元素2,......,元素n},......,{元素1,元素2,......,元素n}}
		//数据类型[][] 数组名 = new 数据类型[x][y];
		int[][] arr01 = new int[3][2];
		System.out.println(arr01);
		System.out.println(arr01[0]);
		System.out.println(arr01[1]);
		System.out.println(arr01[2]);
		//数据类型[][] 数组名 = new 数据类型[x][];
		int[][] arr02 = new int[3][];
		System.out.println(arr02);
		System.out.println(arr02[0]);
		System.out.println(arr02[1]);
		System.out.println(arr02[2]);

		//数据类型[][] 数组名 = new 数据类型[][]{new 数据类型[]{元素1,元素2,......,元素n},new 数据类型[]{元素1,元素2,......,元素n},......,new 数据类型[]{元素1,元素2,......,元素n}}
		int[][] arr03 = new int[][]{new int[]{11,22,33},new int[]{44,55},new int[]{66,77,88,99}};

		//数据类型[][] 数组名 = {new 数据类型[]{元素1,元素2,......,元素n},new 数据类型[]{元素1,元素2,......,元素n},......,new 数据类型[]{元素1,元素2,......,元素n}}
		int[][] arr04 = {new int[]{11,22,33},new int[]{44,55},new int[]{66,77,88,99}};

		//数据类型[][] 数组名 = new 数据类型[][]{{元素1,元素2,......,元素n},{元素1,元素2,......,元素n},......,{元素1,元素2,......,元素n}}
		int[][] arr05 = new int[][]{{11,22,33},{44,55},{66,77,88,99}};

		//数据类型[][] 数组名 = {{元素1,元素2,......,元素n},{元素1,元素2,......,元素n},......,{元素1,元素2,......,元素n}}
		int[][] arr06 = {{11,22,33},{44,55},{66,77,88,99}};
二维数组的元素访问
   格式:
       数组名[x][y]
       x:访问元素所在一维数组在二维数组中的索引
       y:访问元素在一维数组中的索引
		int[][] arr = {{11,22,33},{44,55},{66,77,88,99}};

		System.out.println(arr);
		System.out.println(arr[0]);
		System.out.println(arr[0][0]);
		System.out.println(arr[0][1]);
		System.out.println(arr[0][2]);

		System.out.println(arr[1]);
		System.out.println(arr[1][0]);
		System.out.println(arr[1][1]);

		System.out.println(arr[2]);
		System.out.println(arr[2][0]);
		System.out.println(arr[2][1]);
		System.out.println(arr[2][2]);
		System.out.println(arr[2][3]);

二维数组的遍历

		int[][] arr = {{11,22,33},{44,55},{66,77,88,99}};

		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j < arr[i].length; j++) {
				System.out.println(arr[i][j]);
			}
		}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Patient365

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值