java 4.数组

文章目录

  • 4.数组
    • 4.1数组的概念
    • 4.2 数组的定义
    • 4.3 数组的初始化
    • 4.4 数组下标的有效范围与常见异常
    • 4.5 数组内存分析
    • 4.6 二维数组
      • 4.6.1 创建二维数组
      • 4.6.2 二维数组的赋值
      • 4.6.3 多维数组
      • 4.6.4 通过二维数组输出不同版式的古诗
    • 4.7 不规则数组
    • 4.8 数组的基本操作
      • 4.8.1 数组遍历
      • 4.8.2 填充和替换数组元素
  • 总结

4.数组

如果我们需要存储大量的数据,比如存储100名学生的成绩,这就要重复声明100个变量;再比如让100名学生的成绩全部加一,也是100个变量重复操作,这样太麻烦过于繁琐重复操作过多,无法进行统一的操作。

4.1数组的概念

一组连续的存储空间,存储多个相同数据类型的值。同一种类型数据的集合。其实数组就是一个容器。运算的时候有很多数据参与运算,那么首先需要做的是什么.不是如何运算而是如何保存这些数据以便于后期的运算,那么数组就是一种用于存储数据的方式,能存数据的地方我们称之为容器,容器里装的东西就是数组的元素, 数组可以装任意类型的数据,虽然可以装任意类型的数据,但是定义好的数组只能装一种元素, 也就是数组一旦定义,那么里边存储的数据类型也就确定了。
特点:类型相同,长度固定,可以自动给数组中的元素从0开始编号,方便操作这些元素。

4.2 数组的定义

  • 数组的创建:

元素类型[] 数组名 = new 元素类型[元素个数或数组长度];

  • 声明数组变量
    必须在程序中声明数组,并指定数据类型;声明数据类型为int,容器使用数组那么如何标识数组呢?在java中我们使用[]符号标识,然后接着是定义数组的名称为arr,格式为 int[] arr。注意:int x[] 也是一种创建数组的格式。推荐使用int[] x 的形式声明数组。

  • 创建数组
    要使用一个新的关键字叫做new,new 用来在内存中产生一个容器实体,数据要存储是需要有空间的,存储很多数据的空间用new 操作符来开辟,new int[5]; 这个5是元素的个数。右边这部分就是在内存中定义了一个真实存在的数组,能存储5个元素。注意:new int[5] 做了两件事情,首先使用new int[3] 创建了一个数组,然后把这个数组的引用赋值给数组变量x。

思考: arr是属于什么数据类型?
任何一个变量都得有自己的数据类型。注意这个arr不是int 类型的 。int 代表的是容器里边元素的类型。那么x 是数组类型的,数组是一种单独的数据类型。数据类型分为2大派,分为基本数据类型和引用数据类型。 第二大派是引用数据类型。那么大家现在已经接触到了引用数据类型三种当中的一种。就是数组类型 [] 中括号就代表数组。

思考: int[] arr = new int[5];在内存中发生了什么?
内存任何一个程序,运行的时候都需要在内存中开辟空间.int[] arr = new int[5]; 这个程序在内存中是什么样?这就涉及到了java虚拟机在执行程序时所开辟的空间,那么Java开辟启动了多少空间呢?在后面我们会深入介绍。
定义数组主要有两种格式:
格式一:

元素类型[] 数组名 = new 元素类型[元素个数或数组长度]; 
示例:int[] arr1 = new int[5];
示例:float[] arr2 = new float[5];

格式二:

元素类型[] 数组名 = new 元素类型[]{元素,元素,……}; 
int[] arr1 = new int[]{3,5,1,7}; 
float[] arr2 = {1.3,1.5,1.1,1.7};

注意: 给数组分配空间时,必须指定数组能够存储的元素个数来确定数组大小,体现了数组长度固定的特点;创建数组之后不能修改数组的大小。可以使用length 属性获取数组的大小。

4.3 数组的初始化

  • 数组的声明与赋值
int[] arr = new int[2];
arr[0] = 10;
arr[1] = 20;

另一种方式也可以直接明确数组的长度,以及数组中元素的内容:

int[] arr = new int[]{20,30,40};
int[] arr = {20,30,40};

如果数组初始化中不使用运算符new。需要注意:下列写法是错误的:

int[] arr; 
arr = {20,30,40};

初始化数组,必须将声明,创建,初始化都放在一条语句中个,分开会产生语法错误。

4.4 数组下标的有效范围与常见异常

  • ArrayIndexOutOfBoundsException 索引值越界异常。
    我们进行了数组声明、赋值和访问之后,下面我们来讨论一下数组下标的有效范围。如下面一个例子中:
    在这里插入图片描述
    我们发现长度为5的数组,再给每一个有效的元素依次赋值,再然后完成访问。但是在访问过程中,arr[3]是较为特殊的,那我们就要明确对于一个数组来见,有效的下标范围是0 ~ 数组长度-1,也就是说作为一个长度为三的数组来讲,有效下标范围应该是0 ~ 2,一旦我们访问了不在有效范围的下标,那么就会产生数组下标越界异常。

Exception in thread “main” java.lang.ArrayIndexOutOfBoundsException:
Index 3 out of bounds for length 3

  • NullPointerException 空指针异常
    引用类型变量没有指向任何对象,而访问了对象的属性或者是调用了对象的方法。
    在这里插入图片描述

4.5 数组内存分析

  • 栈内存:栈内存存储的都是局部变量,变量一旦出了自己的作用域,那么就会马上从内存的消失,释放内存空间。

  • 堆内存:堆内存存储的都是对象内存,对象一旦被使用完,并不会马上从内存中消失,而是等待垃圾回收器不定时的把垃圾对象回收,这时候该对象才会消失,释放内存。

  • 凡是以new关键字创建的对象,JVM都会在堆内存中开辟一个新的空间,创建一个新的对象。

  • 对象如果没有变量引用了,那么该对象就是一个垃圾对象了。

在这里插入图片描述
双数组的内存分析

public class Test2 {public static void main(String[] args) {int[] arr1 = new int[2];int[] arr2 = new int[3];System.out.println(arr1);System.out.println(arr1[0]);System.out.println(arr1[1]);System.out.println(arr2);System.out.println(arr2[0]);System.out.println(arr2[1]);System.out.println(arr2[2]);// 给arr1数组的索引为0元素赋值100arr1[0] = 100;// 给arr2数组的索引为0元素赋值200arr2[0] = 200;System.out.println("-----------");System.out.println(arr1);System.out.println(arr1[0]);System.out.println(arr1[1]);System.out.println(arr2);System.out.println(arr2[0]);System.out.println(arr2[1]);System.out.println(arr2[2]);}
}

在这里插入图片描述

4.6 二维数组

我们有个酒店500个房间,并且所有房间都在同一个楼层里,那么拿到499号房钥匙的旅客可能就不高兴了,从1号房走到 499号房要花好长时间,因此每个酒店都不只有一个楼层,而是很多楼层,每一个楼层都会有很多房间,形成一个立体的结构,把大量的房间均摊到每个楼层,这种结构就是二维表结构。在计算机中,二维表结构可以使用二维数组来表示。使用二维表结构表示快捷酒店每一个楼层的房间号的效果如下图所示。

4.6.1 创建二维数组

二维数组可以看作是特殊的一维数组,它有两种声明方式:

数组元素类型 数组名字[][];
数组元素类型[][] 数组名字;
int arr1[][]; 
char[][] arr2;

同一维数组一样,二维数组在声明时也没有分配内存空间,同样要使用关键字new来分配内存,然后才可以访问每个元素。
为二维数组分配内存有两种方式∶

int a[][];
a = new int[2][4];  //直接分配行类
int b[][];
b = new int[2][];   //先分配行,再分配列
b[0] = new int[2];  //给第一行分配列
b[1] = new int[2];  //给第二行分配列

注意: 创建二维数组的时候,可以只声明"行"的长度,而不声明"列"的长度,例如∶

int a[][] = new int[2][]; //可省略列的长度

但如果不声明"行"数量的话,就是错误的写法,例如∶

// 错误写法!int b[][] = new int[][];// 错误写法!int c[][] = new int[][2];

4.6.2 二维数组的赋值

二维数组的初始化方法与一维数组类似,也有3种方式。但不同的是,二维数组有两个索引(即下标),构成由行和列组成的一个矩阵。
在这里插入图片描述
使用三种方式初始化二维数组

public class InitTDArray {public static void main(String[] args) {/* 第一种方式 */int tdarr1[][] = { { 1, 3, 5 }, { 5, 9, 10 } };/* 第二种方式 */int tdarr2[][] = new int[][] { { 65, 55, 12 }, { 92, 7, 22 } };/* 第三种方式 */int tdarr3[][] = new int[2][3]; // 先给数组分配内存空间tdarr3[0] = new int[] { 6, 54, 71 }; // 给第一行分配一个一维数组tdarr3[1][0] = 63; // 给第二行第一列赋值为63tdarr3[1][1] = 10; // 给第二行第二列赋值为10tdarr3[1][2] = 7; // 给第二行第三列赋值为7}
}

从这个例子可以看出,二维数组每一个元素也是一个数组,所以第一种直接赋值方式,在大括号内还有大括号,因为每一个元素都是一个一维数组;第二种使用 new 的方法与一维数组类似; 第三种比较特殊,在分配内存空间之后,还有两种赋值的方式,给某一行直接赋值一个一维数组,或者给某一行的每一个元素分别赋值。开发者可以根据使用习惯和程序要求灵活地选用其中一种赋值方式。

4.6.3 多维数组

比一维数组维数高的叫多维数组,理论上二维数组也属于多维数组。Java也支持三维、四维等多维数组,创建其他多维数组的方法与创建二维数组类似。

int a[][][] = new int[3][4][5];//创建三维数组char b[][][][] = new char[6][7][8][9];//创建四维数纹double c[][][][][]= new double[10][11][12][13][14]; // 建wu维数组

注意: 多维数组在Java中是可以使用的,但因为其结构关系太过于复杂,容易出错,所以不推荐在程序中使用比二维数组更高维数的数组,如果需要存储复杂的数据,推荐使用集合类或自定义类集合类包括List、Map等,这些集合类感兴趣的小伙伴可以了解一下。

4.6.4 通过二维数组输出不同版式的古诗

创建Poetry类,声明一个字符型二维数组,将古诗《春晓》的内容赋值于二维数组,然后分别用横版和竖版两种方式输出,实例代码如下∶

public class Poetry {public static void main(String[] args) {char arr[][] = new char[4][]; // 创建一个4行的二维数组arr[0] = new char[] { '春', '眠', '不', '觉', '晓' }; // 为每一行赋值arr[1] = new char[] { '处', '处', '闻', '啼', '鸟' };arr[2] = new char[] { '夜', '来', '风', '雨', '声' };arr[3] = new char[] { '花', '落', '知', '多', '少' };/* 横版输出 */System.out.println("-----横版-----");for (int i = 0; i < 4; i++) { // 循环4行for (int j = 0; j < 5; j++) { // 循环5列System.out.print(arr[i][j]); // 输出数组中的元素}if (i % 2 == 0) {System.out.println(","); // 如果是一、三句,输出逗号} else {System.out.println("。"); // 如果是二、四句,输出句号}}/* 竖版输出 */System.out.println("\n-----竖版-----");for (int j = 0; j < 5; j++) { // 列变行for (int i = 3; i >= 0; i--) { // 行变列,反序输出System.out.print(arr[i][j]); // 输出数组中的元素}System.out.println(); // 换行}System.out.println("。,。,"); // 输出最后的标点}
}

输出结果如下:
请添加图片描述

4.7 不规则数组

上文讲的数组都是行、列固定的矩形方阵, Java同时也支持不规则的数组,例如二维数组中,不同行的元素个数可以不同,例如∶

a[][] = new int[3][];// 创建二维数组,指定行数,不指定列数
a[0]= new int[5];// 第一行分配5个元素

a[1] = new int[3];// 第二行分配3个元素
a[2] = new int[4];// 第三行分配4个元素 

这个不规则二维数组所占的空间如图所示。

请添加图片描述

输出不规则二维数组中的所有元素

创建IrregularArrax类,声明一个不规则二维数组,输出数组每行的元素个数及各元素的值,代码如下∶

public class IrregularArray {public static void main(String[] args) {int a[][] = new int[3][]; // 创建二维数组,指定行数,不指定列数a[0] = new int[] { 52, 64, 85, 12, 3, 64 }; // 第一行分配5个元素a[1] = new int[] { 41, 99, 2 }; // 第二行分配3个元素a[2] = new int[] { 285, 61, 278, 2 }; // 第三行分配4个元素for (int i = 0; i < a.length; i++) {System.out.print("a[" + i + "]中有" + a[i].length + "个元素,分别是:");for (int tmp : a[i]) { // foreach循环输出数字中元素System.out.print(tmp + " ");}System.out.println();}}
}

4.8 数组的基本操作

4.8.1 数组遍历

遍历数组就是获取数组中的每个元素。通常遍历数组都是使用for循环来实现。遍历一维数组很简单,也很好理解,下面详细介绍遍历二维数组的方法。

遍历二维数组需使用双层for循环,通过数组的length属性可获得数组的长度。

创建Trap类,定义二维数组,实现将二维数组中的每一个元素按照行、列格式进行输出,代码如下∶

public class Trap {public static void main(String[] args) {int b[][] = new int[][] { { 1 }, { 2, 3 }, { 4, 5, 6 } }; // 定义二维数组for (int k = 0; k < b.length; k++) { // 循环遍历二维数组中第一个索引for (int c = 0; c < b[k].length; c++) { // 循环遍历二维数组中第二个索引System.out.print(b[k][c]); // 将数组中的元素输出}System.out.println(); // 输出换行}}
}

本实例中有一个语法需要掌握∶ 如果有一个二维数组a[][],a.length返回的是数组的行数,a[0]. length返回的是第一行的列数量,a[1].length返回的是第二行的列数量。同理,a[n]返回的是第n+1行的列数量,由于二维数组可能是不规则数组,所以每一行的列数量可能不相同,因此在遍历二维数组时,最好使用数组的length属性控制循环次数,而不是用某他变量或常量。

练一练:使用二维数组实现杨辉三角算法。

public class YangHui {// 杨辉三角算法的实现public static void main(String[] args) {// 定义一个长度为10的二维数组int[][] Array_int = new int[10][];// 向数组中记录杨辉三角形的值for (int i = 0; i < Array_int.length; i++) {// 遍历行数Array_int[i] = new int[i + 1];// 定义二维数组的列数// 遍历二维数组的列数for (int j = 0; j < Array_int[i].length; j++) {if (i <= 1) {// 如果是数组的前两行Array_int[i][j] = 1;// 将其设置为1continue;} else {// 如果是行首或行尾if (j == 0 | j == Array_int[i].length - 1)Array_int[i][j] = 1;// 将其设置为1else// 根据杨辉算法进行计算Array_int[i][j] = Array_int[i - 1][j - 1] + Array_int[i - 1][j];}}}for (int i = 0; i < Array_int.length; i++) {// 输出杨辉三角for (int j = 0; j < Array_int[i].length; j++)System.out.print(Array_int[i][j] + "\t");System.out.println();}}
}

运行结果如下:
在这里插入图片描述

4.8.2 填充和替换数组元素

数组中的元素定义完成后,可通过Arrays类的静态方法fill()方法来对数组中的元素进行分配,起到填充和替换的效果。fill()方法可将指定的int值分配给int型数组的每个元素。
语法如下∶

Arrays.fill()(int[] a ,int value)

a∶要进行元素分配的数组。
value∶要存储数组中所有元素的值。

使用 fill() 方法将空数组填满数值

创建 Swap类,通过fill()方法填充数组元素,最后将数组中的各个元素输出,代码如下∶

import java.util.Arrays; //导入java.util.Arrays类public class Swap {public static void main(String[] args) {int arr[] = new int[5]; // 创建int型数组Arrays.fill(arr, 8); // 使用同一个值对数组进行填充for (int i = 0; i < arr.length; i++) { // 循环遍历数组中的元素// 将数组中的元素依次输出System.out.println("第" + i + "个元素是:" + arr[i]);}}
}

总结

  • 为什么数组的索引从0开始?
    为什么索引是从0开始的,而不是从1开始呢?这是继承了汇编语言的传统,从0开始更利于计算机做二进制的运算和查找。

  • 数组长度使用length属性获得,但实际上这个属性只能表示一个一维数组的长度。二维数组使用length属性的方式,其实是将二维数组转为"一维数组[一维数组下]"的形式,即一维数组中的元素仍然是一个一维数组,所以二维数组在遍历时使用的两个length并不是同一个数组的属性。

  • 本章介绍的是数组的创建及使用方法。需要注意的是数组的下标是从0开始,最后一个元素的下标总是"数组名 .length-1"。本章的重点是创建数组、给数组赋值以及读取数组中元素的值。此外,Arrays类还提供了其他操作数组的方法,有兴趣的读者可以查阅相关资料。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/236899.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构和算法-平衡二叉树(定义 插入 删除 时间复杂度)

文章目录 平衡二叉树总览平衡二叉树的定义平衡二叉树的插入调整最小不平衡子树在A的左孩子的左子树中插入导致不平衡在A的右孩子的右子树中插入导致不平衡上述两种的代码思路在A的左孩子的右子树中插入导致不平衡在A的右孩子的左子树中插入导致不平衡 填个坑练习查找效率分析小…

锁相放大器(LIA)基本原理

本文介绍锁相放大器(LIA)基本原理。 锁相放大器(LIA)&#xff0c;英文名称&#xff1a;Lock-In Amplifier&#xff0c;在微弱信号检测领域使用非常广泛&#xff0c;比如科研电生理信号测量&#xff0c;传感器信号测量等。本文从理论上分析锁相放大器(LIA)基本原理。 1.基本概…

vivado生成时钟分析

生成的时钟 本节讨论生成的时钟&#xff0c;包括&#xff1a; •关于生成的时钟 •用户定义的生成时钟 •自动衍生时钟 •自动衍生时钟 关于生成的时钟 生成的时钟在设计内部由称为时钟修改块&#xff08;用于例如MMCM&#xff09;&#xff0c;或者通过一些用户逻辑。生…

[JS设计模式]Command Pattern

文章目录 举例说明优点缺点完整代码 With the Command Pattern, we can decouple objects that execute a certain task from the object that calls the method. 使用命令模式&#xff0c;我们可以将执行特定任务的对象与调用该方法的对象解耦。 怎么理解 执行特定任务的对…

基于Java (spring-boot)的课程管理系统

一、项目介绍 ​近年来&#xff0c;随着网络学校规模的逐渐增大&#xff0c;人工书写数据已经不能够处理如此庞大的数据。为了更好的适应信息时代的高效性&#xff0c;一个利用计算机来实现学生信息管理工作的系统将必然诞生。基于这一点&#xff0c;设计了一个学生信息管理系统…

Mybatis基本操作

目录 准备工作 删除操作 预编译SQL 增加操作 获取返回的主键 更新操作 准备工作 准备数据库表 emp创建一个新的springboot工程&#xff0c;选择引入对应的起步依赖&#xff08;mybatis、mysql驱动、lombok&#xff09;application.properties中引入数据库连接信息创建对应…

PSP - 蛋白质与蛋白质的扩散对接 DiffDock-PP 算法

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/135115528 DiffDock-PP is a new approach to rigid-body protein-protein docking that is based on a diffusion generative model that learns…

软件工程快速复习(期末急救)

每个同学要假想自己是一个项目经理&#xff0c;去完成一个软件项目&#xff0c;比如医院管理系统&#xff0c;自动设备控制系统等&#xff0c;以面向结构的软件工程方法&#xff0c;说出完成项目的步骤&#xff0c;涉及到的具体技术。初步了解面向对象的方法的与面向结构的方法…

【java】java学习笔记

1. 快速入门 // Hello类 public class Hello {// main方法public static void main(String[] args) {System.out.println("hello world!");} } 在控制台输入以下命令&#xff0c;对.java文件&#xff08;源文件&#xff09;进行编译操作&#xff0c;生成Hello.clas…

每日一题,二维平面

给你 二维 平面上两个 由直线构成且边与坐标轴平行/垂直 的矩形&#xff0c;请你计算并返回两个矩形覆盖的总面积。 每个矩形由其 左下 顶点和 右上 顶点坐标表示&#xff1a; 第一个矩形由其左下顶点 (ax1, ay1) 和右上顶点 (ax2, ay2) 定义。 第二个矩形由其左下顶点 (bx1, …

初学gitrepo的种种

经过各种折腾之后&#xff0c;发现git其实还是很简单的&#xff1b; 首先你需要两台机器&#xff0c;一台作为服务器&#xff0c;一台作为开发机器&#xff0c;开发机器从服务器上拉取代码。 目 目录 git建仓 开发机器拉取代码 初始化仓代码 repo管理 repo工具的下载 …

汽车制造厂设备故障预测与健康管理PHM

在现代汽车制造工业中&#xff0c;设备的可靠性和稳定性对于保证生产线的高效运行至关重要。为了提高生产效率、降低维修成本以及确保产品质量&#xff0c;汽车制造厂逐渐采用设备故障预测与健康管理&#xff08;PHM&#xff09;系统&#xff0c;以实现对设备状态的实时监测和预…

算法基础之快速幂求逆元

快速幂求逆元 核心思想&#xff1a; 逆元&#xff1a; 逆元 ap-2 mod p #include<iostream>#include<algorithm>using namespace std;typedef long long LL;LL pmi(int a,int b,int c){LL res 1;while(b){if(b & 1) res res * a %c;b >> 1;a (LL)…

Jenkins的文档翻译

官网Jenkins.io Jenkins用户文档 欢迎来到Jenkins用户文档-为那些想要使用Jenkins的现有功能和插件特性的人。如果你想通过开发自己的Jenkins插件来扩展Jenkins的功能&#xff0c;请参考extend Jenkins(开发者文档)。 詹金斯是什么? Jenkins是一个独立的、开源的自动化服务…

第七节TypeScript 循环

1、简述 有的时候&#xff0c;我们可能需要多次执行同一块代码。一般情况下&#xff0c;语句是按顺序执行的&#xff1a;函数中的第一个语句先执行&#xff0c;接着是第二个语句&#xff0c;依此类推。 循环语句允许我们多次执行一个语句或语句组。 循环语句流程图&#xff…

python学习笔记--异常捕获

异常场景 numinput("input you number:") n9000 try:resultn/int(num)print({} 除以num 结果为{}.format(n,result)) except ZeroDivisionError as err:print("0不可以作为除数&#xff0c;出现报错{}".format(err)) except ValueError as err:print(&quo…

【lesson21】MySQL复合查询(2)子查询

文章目录 子查询测试要用到的表测试要用到的数据单行子查询案例 多行子查询案例 多列子查询案例 在from子句中使用子查询案例 合并查询union案例union all案例 子查询 子查询是指嵌入在其他sql语句中的select语句&#xff0c;也叫嵌套查询 测试要用到的表 测试要用到的数据 单…

坚持提升这个能力,让你越来越强大

哈喽&#xff0c;你好啊&#xff01;我是雷工。 今天在读《张一鸣管理日志》时&#xff0c;看到这么一句话&#xff1a; “产品创新要从根本上解决问题&#xff0c;而不是想办法绕过问题&#xff0c;解决的问题很可能就是将来的核心竞争力。” 这让我想起了亚马逊公司&#x…

LeetCode 热题100——单调栈

​ 个人主页&#xff1a;日刷百题 系列专栏&#xff1a;〖C语言小游戏〗〖Linux〗〖数据结构〗 〖C语言〗 &#x1f30e;欢迎各位→点赞&#x1f44d;收藏⭐️留言&#x1f4dd; ​ ​ 写在前面&#xff1a; 递增单调栈&#xff1a;栈中元素从栈底到栈顶依次增大 递减单调栈…

3D模型人物换装系统(二 优化材质球合批降低DrawCall)

3D模型人物换装系统 介绍原理合批材质对比没有合批材质核心代码完整代码修改总结 介绍 本文使用2018.4.4和2020.3.26进行的测试 本文没有考虑法线贴图合并的问题&#xff0c;因为生成法线贴图有点问题&#xff0c;放在下一篇文章解决在进行优化 如果这里不太明白换装的流程可以…