数组
学习目标:- 1. jvm内存图入门
- 2. 一维数组的使用
- 3. 二维数组的使用
- 4. 数组的内存结构
- 5. 数组中常见算法
- 6. 数组中常见的异常
复制代码 一、JVM内存图入门
java程序运行在jvm上,jvm内存主要分为五块,结构如下:
每块内存负责的职责如下:
- Java虚拟机栈(Java Virtual Machine Stacks):描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(Stack Frame),栈帧中存储着局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行完成的过程,会对应一个栈帧在虚拟机栈中入栈到出栈的过程。与程序计数器一样,Java虚拟机栈也是线程私有的。
局部变量和引用地址都是在栈内存中。
- 堆:此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。这一点在Java虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配。
- 方法区:用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。方法区存放的数据只有一份
- 本地方法栈(Native Method Stack):与Java虚拟机栈作用很相似,它们的区别在于虚拟机栈为虚拟机执行Java方法(即字节码)服务,而本地方法栈则为虚拟机使用到的Native方法服务。例如调用本地c/c++的方法。
- 程序计数器:程序计数器是记录当前线程所执行的指令行数。
二、数组的概述
2.1 为什么需要数组
为什么要有数组?在开发中,我们常常需要存取很多相同类型的数据,用变量的方式需要定义很多变量,不方便管理。所以引入数组的概念,一次存取多个相同类型的数据。数组有两个一定,一个类型一定,一个是大小一定。
2.2 数组的基本概念
数组中存在着一些重要的概念,如下所示:
- 数组名:数组的名称,数组内存的首地址
- 下标名(索引):数组元素的序号索引,从0开始
- 元素:数组中存放的内容
- 长度 :数组的长度
三、一维数组的使用
3.1 数组的定义
一维数组的定义语法如下:
示例:- /**
- * 数组定义
- */
- public class ArrayDemo1 {
- public static void main(String[] args) {
- //定义数组
- int[] arr1;
- String [] arr2;
- }
- }
复制代码 3.2 数组的初始化
数组动态初始化语法:
示例:- /**
- * 数组定义,以及动态初始化
- */
- public class ArrayDemo1 {
- public static void main(String[] args) {
- //定义数组
- int[] arr1;
- //数组动态初始化
- arr1 = new int[4];
- arr1[0] = 10;
- arr1[1] = 20;
- arr1[2] = 30;
- arr1[3] = 40;
- //取值
- System.out.println(arr1[0]);
- System.out.println(arr1[1]);
- System.out.println(arr1[2]);
- System.out.println(arr1[3]);
- }
- }
复制代码 数组静态初始化语法:
示例:- /*
- 数组的定义与静态初始化
- */
- public class ArrayDemo2 {
- public static void main(String[] args) {
- //数组的声明
- // String[] arr = new String[]{"乔峰","段誉","杨过"};
- //简写
- String[] arr = {"乔峰","段誉","杨过"};
- //取值
- System.out.println(arr[0]);
- System.out.println(arr[1]);
- System.out.println(arr[2]);
- }
- }
复制代码 3.3 数组元素的引用
引用数组元素内容需要注意以下几点:
- 定义并用运算符new为之分配空间后,才可以引用数组中的每个元素;
- 数组元素的引用方式:数组名[数组元素下标]
- 数组元素下标可以是整型常量或整型表达式。如a[3] , b , c[6*i];
- 数组元素下标从0开始;长度为n的数组合法下标取值范围: 0 —>n-1;如int a[]=new int[3]; 可引用的数组元素为a[0]、a[1]、a[2]
- 每个数组都有一个属性length指明它的长度,例如:a.length 指明数组a的长 度(元素个数) 。数组一旦初始化,其长度是不可变的
示例1:数组元素的引用- /**
- * 数组元素的引用
- */
- public class ArrayDemo3 {
- public static void main(String[] args) {
- //数组的定义
- int[] arr = {1,3,5,7,9};
- //查看数组的长度
- System.out.println(arr.length);
- // 查看数组内容
- System.out.println(arr[0]);
- System.out.println(arr[1]);
- System.out.println(arr[2]);
- System.out.println(arr[3]);
- System.out.println(arr[4]);
- // 数组下标超过最大下标会越界,报异常ArrayIndexOutOfBoundsException
- System.out.println(arr[5]);
- }
- }
复制代码 示例2:数组的循环赋值与取值- /**
- * 数组的循环赋值与取值
- */
- public class ArrayDemo4 {
- public static void main(String[] args) {
- //定义数组
- int[] arr = new int[5];
- //循环赋值
- for (int i = 0; i < arr.length; i++) {
- arr[i] = i*5;
- }
- //循环取值
- for (int i = 0; i < arr.length ; i++) {
- System.out.println(arr[i]);
- }
- }
- }
复制代码 3.4 数组的注意事项
数组在使用过程中需要注意以下几点:
- 数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。
- 创建数组对象会在内存中开辟一整块连续的空间,而数组名中引用的是这块连续空间的首地址。
- 数组的长度一旦确定,就不能修改。
- 数组的分类:
- 按照维度:一维数组、二维数组、三维数组、…
- 按照元素的数据类型分:基本数据类型元素的数组、引用数据类型元素的数组(即对象数组)
3.5 forEach的应用
forEach可以遍历数组或集合容器中的数据,语法如下:
示例:- /**
- * forEach遍历
- */
- public class ArrayDemo5 {
- public static void main(String[] args) {
- //数组定义
- int[] arr = {1,3,5,7,9};
- //数组遍历
- for(int num : arr){
- System.out.println(num);
- }
- }
- }
复制代码 3.6 数组元素默认值
当数组元素没有赋值时,是存在默认值的,默认值如下:
3.7 一维数组内存图
3.8 小结
- 数组的基本使用
- 数据类型可以是基本类型或引用类型
- 数组类型固定长度不变
- 数组默认值
- 数组的内存图
四、一维数组练习题
4.1 数组赋值练习
将班级所有同学名字录入到一个一维数组中 。
参考答案:
[code]/*** 将班级所有同学名字录入到一个一维数组中*/public class ArrayTest1 {public static void main(String[] args) {//1.创建大小为5的String类型数组String[] names = new String[5];//2.创建扫描仪对象Scanner input = new Scanner(System.in);for(int i=0;i |