1.5 Java 数组

本文是课上资料的总结非原创没有转载地址

Java数组

  • 变量:内存中一块存储空间,存储数据的基本单元。只能存一个数据

为什么要使用数组?

  • 如何存储100名学生的成绩?
    • 办法:使用变量存储,重复声明100个double类型变量即可。
    • 缺点:麻烦,重复操作过多。
  • 如何让100名学生成绩全部+1?
    • 办法:100个变量重复相同操作,直至全部完成。
    • 缺点:无法进行统一的操作。

1.数组的概念

  • 数组概念:一组连续的存储空间,存储多个相同数据类型的值。
  • 特点
    1. 类型相同
    2. 长度固定

2.数组的创建

  • 声明int数组类型变量定义变量名为a。
  • 分配长度为5的连续空间
public class TestCreateArray {
	public static void main(String[] args) {
		int[] a = new int[5];
	}
}

数组内存

2.1 数组创建语法

  1. 先声明、再分配空间:
// 先声明、再分配空间:
数据类型[] 数组名;
数组名 = new 数据类型[长度];
  1. 声明并分配空间:
// 声明并分配空间:
数据类型[] 数组名 = new 数据类型[长度];
  1. 声明并赋值(繁):
// 声明并赋值(繁):
数据类型[] 数组名 = new 数据类型[]{value1, value2, value3, ...};
  1. 声明并赋值(简):
// 声明并赋值(简):
数据类型[] 数组名 = {value1, value2, value3, ...};    // 显示初始化,注意:不可换行

2.2 数组的默认值

类型默认值
整数0
小数0.0
字符\u0000
布尔false
其他null

3.数组的下标

数组内存详解

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

3.1 使用

public class TestCreateArray {
	public static void main(String[] args) {
		int[] a = new int[5];    // 创建数组
		// 依次赋值
		a[0] = 5;
		a[1] = 3;
		a[2] = 4;
		a[3] = 7;
		a[4] = 10;
		// 依次取值
		System.out.println(a[0]);
		System.out.println(a[1]);
		System.out.println(a[2]);
		System.out.println(a[3]);
		System.out.println(a[4]);
	}
}
  • 结果:
5
3
4
7
10

3.2 下标范围

  • 数组有效长度:有效下标范围:0~数组长度-1
public class TestCreateArray {
	public static void main(String[] args) {
		int[] a = new int[5];    // 创建数组    有效下标范围:0~数组长度-1
		// 依次赋值
		a[0] = 5;
		a[1] = 3;
		a[2] = 4;
		a[3] = 7;
		a[4] = 10;
		// 依次取值
		System.out.println(a[0]);
		System.out.println(a[1]);
		System.out.println(a[2]);
		System.out.println(a[3]);
		System.out.println(a[4]);
		System.out.println(a[5]);    // 访问无效下标,会导致数组下标越界
	}
}
  • 结果:数组越界异常
    java.lang.ArrayIndexOutOfBoundsException:5

4.数组的遍历

数组名.length可动态获得数组长度。

4.1 for

  • 遍历:从头至尾,逐一对数组的每个元素进行访问。
  • 使用循环变量i充当下标,逐一访问数组中的每个元素。
public class TestVisitArray {
	public static void main(String[] args) {
		int[] a = new int[5];
		a[0] = 5;
		a[1] = 3;
		a[2] = 4;
		a[3] = 7;
		a[4] = 10;
		for (int i = 0; i < a.length; i++) {
			System.out.println(a[i]);
		}
	}
}

4.2 增强for(foreach)

  • 在JDK1.5之后,Java提供了增强for简化数组或集合的遍历
  • 语法
for (数组元素类型 元素变量 : 数组) {
	// 元素变量代表数组中每个元素
}
  • 缺点:不能使用下标

5.数组的内存分析

  • 程序运行中有两块重要的存储空间【个人感觉非常非常重点】
      1. 存储基础类型数据以及引用类型的地址
      2. 特点1:空间比较小,存储速度较快 jdk1.5之前256k jdk1.5之后1M
      3. 特点2:先进后出
      1. 存储引用类型的实际数据
      2. 特点:空间比较大,存储速度慢
public static void main(String[] args) {
	// 1.创建变量
	int num = 10;
	// 2.创建数组
	int[] arr = new int[3];
	arr[0] = 10;
	arr[1] = 8;
	arr[2] = 15;
}

数组内存空间分析2

public static void main(String[] args) {
	int[] arr = new int[3];
	int[] arr2 = {100, 200, 300, 400, 500};
	arr = arr2;
	for (int i : arr) {
		System.out.println(i);
	}
}

数组内存空间分析3

6.数组的扩容

  • 创建数组时,必须显示指定长度,并在创建之后不可更改长度。
  • 扩容的思想
    1. 创建大于原数组长度的新数组。
    2. 讲原数组中的元素依次复制到新数组中。
      数组扩容

6.1 复制的方式

  • 循环将原数组中所有元素逐一赋值给新数组。
  • 使用for循环实现。
  • Array.copyOf(原数组, 新长度); // 返回带有原值的新数组。

6.2 地址的替换

  • 数组作为引用类型之一,其变量中存储的是数组的地址。
  • 完成元素赋值后,需将新数组地址,赋值给原变量进行替换。
    地址替换

7.数组的排序

  • 冒泡排序:相邻的两个数值比较大小,互换位置。
  • 选择排序:固定值与其他值依次比较大小,互换位置。
  • JDK排序java.util.Arrays.sort(数组名); // JDK提供(升序)

8.数组的应用

8.1数组类型的参数

public class TestArrayParameter {
	public static void main(String[] args) {
		int[] nums = {111, 222, 333, 444, 555};    // 假设nums地址为:0x0000A001
		printArray(nums);
	}
	public static void printArray(int[] oneArray) {    // 参数传入后oneArray地址为:0x0000A001
		for (int i = 0; i < oneArray.length; i++) {
			System.out.println(oneArray[i]);
		}
	}
}
/*
运行结果:
111
222
333
444
555
*/
  • 方法调用时,将nums中的地址赋值给oneArray,此时二者指向同一数组。

8.2数组类型的返回值

public class TestReturnValue {
	public static void main(String[] args) {
		int[] oa = {};    // 假设地址0x0000A111
		int[] na = expand(oa);
		for (int i = 0; i < na.length; i++) {
			System.out.println(na[i]);
		}
	}
	public static int[] expand(int[] oldArray) {    // 0x0000A111
		int[] newArray = new int[oldArray.length*2];    // 0x0000B222
		for (int i = 0; i < oldArray.length; i++) {
			newArray[i] = oldArray[i];
		}
		return newArray;    // 0x0000B222
	}
}
/*
运行结果:
111
222
333
444
555
0
0
0
0
0
*/
  • 返回长度为10的newArray
  • 创建新数组,长度为原数组的2倍,新数组中保留原有数据,返回新数组。

8.3数组类型的返回值

public class TestArrayParameter {
	public static void main(String[] args) {
		printArray(111, 222, 333, 444, 555);    // 可为可变长参数赋予0 ~ N个实际参数
	}
	public static void printArray(int... oneArray) {    // 定义int型可变长参数
		for (int i = 0; i < oneArray.length; i++) {
			System.out.println(oneArray[i]);
		}
	}
}
/*
运行结果:
111
222
333
444
555
*/
  • 概念:可接收多个同类型实参,个数不限,使用方式与数组相同。
  • 语法数据类型... 形参名; // 必须定义在形参列表的最后,且只能有一个。

9.二维数组

9.1 概念

  • 概念:一维数组中的一维数组;数组中的元素还是数组。
    二维数组

9.2 二维数组创建语法

// 先声明、再分配空间:
数据类型[][] 数组名;
数组名 = new 数据类型[高维长度][低维长度];
  1. 声明并分配空间:
// 声明并分配空间:
数据类型[][] 数组名 = new 数据类型[高维长度][低维长度];
  1. 声明并赋值(繁):
// 声明并赋值(繁):
数据类型[][] 数组名 = new 数据类型[高维长度][];    // 不规则数组,自行new低维数组
  1. 声明并赋值(简):
// 声明并赋值(简):
数据类型[][] 数组名 = {{v1, v2, v3}, {v4, v5}, {v6, v7, v8, v9}};    // 显示初始化

9.3 二维数组的赋值

public class Test2DArray {
	public static void main(String[] args) {
		int[][] array = new int[3][5];
		array[0][0] = 10;
		array[0][3] = 20;
		array[1][1] = 30;
		array[1][2] = 40;
		array[2][4] = 50;
	}
}

二维数组逻辑

  • 使用双下标访问二维数组中的元素,
  • 第一个下标代表,行号(高维下标),
  • 第二行下标表示,列号(低维下标)。

9.4 二维数组的内存分配

二维数组的内存分配

  • 高维数组中的每一个元素,保存了低维数组的地址,访问array[0]等价于在访问0x0000A111

9.5 二维数组的访问

public class Test2DArray {
	public static void main(String[] args) {
		int[][] array = new int[3][5];
		array[0][0] = 10;
		array[0][3] = 20;
		array[1][1] = 30;
		array[1][2] = 40;
		array[2][4] = 50;
		for (int i = 0; i < array.length; i++) {
			for (int j = 0; j < array[i].length; j++) {
				System.out.print(array[i][j]);
			}
			System.out.println();
		}
	}
}
  • 访问低维长度:array[i].length首个低维数组的长度
  • 访问低维数组元素:array[i][j]首个低维数组的首个元素

课堂案例

  • 杨辉三角
public class PascalTriangle {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入杨辉三角的行数:");
		int n = sc.nextInt();
		int[][] nums = new int[n][];
		for (int i = 0; i < n; i++) {
			// 创建内层数组
			nums[i] = new int[i + 1];
			// 遍历数组
			for (int j = 0; j < nums[i].length; j++) {
				if (j == 0 || j == i) {
					nums[i][j] = 1;
				} else {
					nums[i][j] = nums[i - 1][j - 1] + nums[i - 1][j];
				}
			}
		}
		
		for (int i = 0; i < nums.length; i++) {
			for (int k = nums.length-i-1; k > 0; k--) {
				System.out.print(" ");
			}
			for (int j : nums[i]) {
				System.out.print(j + " ");
			}
			System.out.println();
		}
	}
}

总结

  • 数组的概念
    一组连续的存储空间,存储多个相同数据类型的值。
  • 数组的声明与赋值
数据类型[] 数组名 = new 数据类型[长度];
数组名[下标] =;
  • 数组的遍历
    从头至尾,逐一对数组的每个元素进行访问。
  • 数组的排序
    冒泡排序、选择排序、JDK快速排序。
  • 数组的应用
    数组复制、数组扩容、数组参数、数组返回值、二维数组。

作业

  1. 定义一个函数,获取某个数组中的最小值
  2. 定义一个数组,数组成员10个,找出数组中最大数连同下标一起输出
  3. 给定一个整型数组,数组成员10个,求该数组中第二大的数的下标
  4. B哥去参加青年歌手大奖赛,有10个评委打分,(去掉一个最高一个最低)求平均分?
  5. 利用选择排序对数据进行降序排序
  6. 定义数组,存放5个学生的成绩【成绩值自己设定】,将成绩从大到小排序,获得成绩之和,平均成绩,最小成绩,最大成绩。
  7. 定义一个长度为10的int数组,统计数组中的最大值、最小值、以及奇数和偶数的个数
  8. 提取一个方法,将指定数组中的数组元素进行反转
    例如:{10,23,2,45,6}—>{6,45,2,23,10}
  9. 将一个数组逆序输出
  10. 输入数组,最大的与第一个元素交换,最小的与最后一个元素交换,输出数组
  11. 有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中

面试题

  1. 基本数据类型和引用数据类型之间的区别
  2. 在Java中,声明一个数组过程中,是如何分配内存的
  3. 分别使用冒泡和选择对已知数组进行排序
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值