数组的定义与应用,你了解多少?|本次数组

这次给大家介绍一下数组的定义和应用。废话不多说,正文开始!

一、 数组的基本用法

1.什么是数组

数组本质上允许我们“批量”创建相同类型的变量。

例如:

如果需要表示两个数据,那么直接创建两个变量为int a;诠释 b

如果需要表示五个数据,可以创建五个变量 int a1;诠释a2;诠释a3;诠释a4;诠释a5;

图片[1]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

但是如果你需要表示 10,000 个数据,那么你就不能创建 10,000 个变量。这时候就需要使用数组来帮助我们批量创建。

上面是一个整数数组。

注意:在 Java 中,数组中包含的变量必须是同一类型。

2. 创建数组

基本语法

图片[2]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

在上面的例子中,我们以整数数组为例,创建一个int[]类型的数组数组,存储5个整数数据。解释了数组创建的用法。Java 数组的创建与 C 语言非常相似。相似,但有区别。

C语言版本数组创建:

Java版本数组创建:

我们可以看到两种写作方式之间的区别。在 Java 中,[ ] 必须位于数据类型旁边。

数组的数据连续存储在内存中。继续以上面的代码为例:

图片[3]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

数组的每个元素都有对应的下标,下标->从0开始。如果我们想在这个数组中找到某个数据,我们通过数组的下标来访问它。

注意:数组也称为集合,包含一组相同类型的数据!!下标从位置 0 开始。

3.如何定义一个数组

定义方法一

我们上面写的代码是定义和初始化一个数组。

这种方式只定义了一个数组。这是我们定义数组的第一种方式。而这种方式定义的数组的默认大小是0.

定义 2

这里也定义了一个数组,但是这个数组定义使用了new等关键字为数组分配了一块内存,而这块内存有10条数据可以存储。

图片[4]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

int[10] 分配的连续内存空间。

不过此时我们还没有初始化数组数组,所以此时数组的十个数据的默认值为0.

定义三

在Java中,初始化后=左边的[]不能填数字,而=右边的[]只能在第二个定义中赋值。

在定义模式三

图片[5]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

总结一下定义数组的三种方式:

在这三种方式中,Java 中定义数组最常见的方式是方式一。

4. 数组的使用

(1)获取长度

预防措施

使用 arr。获取数组的长度。这个操作是成员访问操作符,后面会在面向对象中经常用到。

代码示例:

编译结果:

图片[6]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

(2)访问数组中的元素

数组访问方法:

图片[7]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

预防措施:

1.使用 [ ] 按下可索引数组元素。需要注意的是下标从0开始计数

2.使用 [ ] 操作来读取和修改数据。

3.下标访问操作不能超出有效范围[0, ),如果超出有效范围会出现下标越界异常

代码示例:

图片[8]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

编译结果:

图片[9]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

(3)下标越界

数组下标从0开始,范围为[0, arr.),左闭右开区间,或[0, arr.-1]。

如果我们将下标的值放在数组的边界之外……

如下

编译结果:

图片[10]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

(4) 遍历数组

所谓“遍历”,是指访问数组中的所有元素一次,不再重复。通常需要与循环语句匹配

1. 遍历方法(一)—–for循环

图片[11]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

编译结果:

图片[12]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

我们可以看到,for循环是用来一个一个遍历数组中的元素,并打印出来的。

2.遍历方法(二)—->for-each

for-each 是使用 for 循环的另一种方式。可以更方便的完成数组的遍历。它可以避免错误地编写循环条件和更新语句。

for-each 的基本使用

图片[13]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

代码示例:

图片[14]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

编译结果:

图片[15]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

for-each遍历原理

遍历数组中的每个元素,取出每个元素,赋值给x,最后打印x,直到遍历完数组中的所有元素。

我们已经介绍了两种遍历方式,那么for循环和for-each有什么区别呢?

for循环可以获取数组下标,而for-each无法获取数组下标,所以for-each只能遍历所有c语言字符数组逆序输出,不能修改或操作数组元素。

3. 遍历方法(三) – 使用操作数组的工具类打印数组

它是一个用于操作 Java 数组的工具类。如果你想对数组做一些事情,你可以通过它来做。当然,有些事情是他做不到的。

例如:我们要打印一个数组,我们原本是用for循环或者for-​​each写的,但是我们也可以使用类来打印。

通过JDK的工具文档,我们找到了对应的工具类。

图片[16]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

好吧,我们对 arr 数组进行如下操作:

图片[17]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

编辑结果:

图片[18]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

5.在内存中存储数组

我们在上一篇博客中已经简单介绍了Java中内存区域的划分,那么今天我们知道了数组的引用类型,那么它是如何存储在内存中的呢?

下面简单回顾一下Java的内存区域

图片[19]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

我们知道,局部变量存放在Java虚拟机栈上,而数组的数据存放在堆上。数组的数据在堆上有一个特定的地址,而数组的变量其实就是这组数据的地址。栈上的这个变量根据这个地址找到堆上的数据。

数组的具体存储如下图所示:

图片[20]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

当心:

图片[21]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

图片[22]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

图片[23]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

上图是arr所指向的数据在堆中的地址。这个地址不是真实地址,是通过官方地址哈希得到的。但是我们可以把它当作真正的地址,因为这个地址也是唯一的。

那么为什么要对真实地址进行哈希处理呢?

这就是Java的安全性,它不会轻易暴露自己数据的地址。

二、数组作为方法参数

1.基本用法

代码示例:打印数组内容

图片[24]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

在这段代码中

1.int [ ] a 是函数的形参,int [ ] arr 是函数实参。

2.如果需要获取数组的长度c语言字符数组逆序输出,也可以使用a.

2.理解引用类型

在上一篇博客Using 中,我们介绍了一个使用方法交换两个变量的具体案例。现在让我们回顾一下。

(1) 参数传递内置类型

图片[25]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

我们使用内置类型作为参数来交换变量,但是最终编译的结果是两个变量没有交换。

为什么是这样?

图片[26]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

交换形参的值而不影响实参的值。

(2)参数传递数组类型

图片[27]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

我们使用数组作为参数来交换变量。编译运行后,我们发现两个变量的值交换成功了。此时,数组名 arr 是一个“引用”。传递参数时,参数是通过引用传递的。

那么为什么引用传递类型可以对形参和实参进行操作呢?

在这里,我们必须从记忆开始。上面我们介绍了数组在内存中的存储。

图片[28]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

我们可以知道,存储在栈中的数组变量实际上存储了堆中数据的地址。当我们将 arr 数组作为参数传递给方法时,我们传入的是堆中数据的地址。在方法内部,我们可以根据这个地址找到堆中的数据,然后修改数据,从而实现形参改变实参的操作。

图片[29]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

总结:

所谓的“引用”本质上只是存储了一个地址。Java将数组设置为引用类型,这样数组参数的后续传参只传入数组的地址到函数参数中。这样就避免了对整个数组Copy的需要(数组可能很长,所以复制的代价会很大)。

3.识别空

引用类型的值为 0 为空。

图片[30]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

当我们将 null 分配给引用类型 arr 时,这意味着什么?

表示引用 arr,它不指向任何对象。

当我们运行这段代码时,显示的结果是空的,而不是一个值0.

图片[31]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

那么我们再来看看另一个问题。当我们将 null 分配给 arr 时,arr 数组的长度是多少?

我们猜测它可能是 0,现在让我们运行代码。

结果如下:

图片[32]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

此时编辑器报错,错误类型:空指针异常。

嗯,这时候我们就可以知道给arr赋值了null,arr没有指向任何数组对象,也没有在堆上开辟内存空间,所以找不到它的长度。

总结:

空值。任何事情,都会发生空指针异常错误。

经验:以后只要出现这样的异常,肯定是这个引用为空。

4.JVM内存区域划分介绍

一个宿舍楼将分为几个不同的区域:大一学生、大二学生……计算机专业、通信专业……

记忆也是类似的。这条大走廊被分成许多部分,每个区域存储着不同的数据。

JVM的内存分为几个区域,如图:

图片[33]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

程序计数器(PC):

只是一个小空间,保存下一条要执行的指令的地址。

虚拟机堆栈(JVM 堆栈):

关键是存储局部变量表(当然还有其他信息)。我们刚刚创建的int[] arr之类的存储地址的引用就存储在这里。

本机方法栈(Stack)

本机方法堆栈类似于虚拟机堆栈。唯一保存的是方法的局部变量。在某些版本的 JVM 实现中(例如),本机方法堆栈和虚拟机堆栈是在一起的。

堆:

JVM 管理的最大内存区域。用 new 创建的对象保存在堆上(比如之前的 new int[]{1, 2, 3} )

方法区(Area):

用于存储类信息、常量、静态变量、实时编译器编译的代码等数据已经被虚拟机加载。方法编译的字节码存放在这个区域。

运行时常量池(Pool):

它是方法区的一部分,存储文字(字符串常量)和符号引用。(注意从JDK1.7开始,运行时常量池在堆上)

关于上面的划分方法,后面我们会慢慢了解。这里我们重点了解虚拟机栈和堆。

图片[34]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

1.局部变量和引用存放在栈上,新对象存放在堆上。

2.堆空间很大,栈空间比较小。

3.堆是整个JVM共享的,每个线程都有一个栈(一个Java程序中可能有多个栈)。

三、数组作为方法的返回值

代码示例:

图片[35]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

此代码可行,但破坏了原始数组。有时我们不想破坏原来的数组,需要在方法内部新建一个数组,并有方法返回。

修改后的代码:

图片[36]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

这样,原始数组就不会被破坏。

另外,由于数组是引用类型,所以返回时只返回数组的首地址给函数调用者,不复制数组的内容,效率更高。

四、数组练习

1.数组转字符串

题目要求:

实现一种将整数数组转换为字符串的方法。

例如数组 {1, 2, 3} ,返回字符串为“[1, 2, 3]”,注意逗号的位置和个数。

图片[37]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

2.数组复制

数组复制方法

1.for 循环复制

图片[38]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

在这个拷贝方法中,我们首先通过new拷贝一个与arr长度相同的新数组,然后通过for循环将arr数组的内容一一赋值给拷贝数组,达到最终数组拷贝的效果。

2.数组的工具类

1)()

我们先通过JKD的工具文档看一下复制工具的使用方法

功能:复制指定的数组,截断或用零填充(如果需要),使副本具有指定的长度。

下面我们来看看Java中方法的具体实现

图片[39]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

首先.()的返回类型是int[],第一个参数是原数组(要复制的数组),第二个参数是新数组的长度(可以自己设置),如果新数组的长度比原数组长,如果长,大于原数组长度的元素用0填充。具体如下……

图片[40]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

(2)()

我们先通过JDK文档看一下这个工具类的功能

功能:将指定数组的指定范围复制到一个新数组中。

下面我们来看看Java中方法的具体实现

图片[41]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

该方法的返回类型是 int [ ] ,第一个参数是原始数组,第三个参数二、是要复制的原始数组数据的下标。一定要记住,它是一个左闭右开的区间,[ from , to )。

代码示例

图片[42]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

3.。

图片[43]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

我们打开方法的具体实现,发现并没有上述复制方法的实现过程。如上一节所述,这是一种本地方法。

本机方法

1. 在本机方法堆栈上运行

2.底层由C/C++代码实现

. 没有返回值,第一个参数是原数组(要复制的数组),第二个参数是要复制的原数组的下标,第三个参数是目标数组,第四个参数是下标目标数组。index,第五个数组是要复制的长度。

代码示例:

图片[44]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

当心:

. 最后一个参数——要复制的数组长度,这个数据不能超过原数组的长度,否则编辑器会报错:数组越界。

4..clone —-> 生成当前数组的副本

功能:生成当前数组的副本。

代码示例:

图片[45]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

3. 查找数组中最大的元素

题目内容:给定一个整数数组,求其中最大的元素(类似于求最小元素)

代码:

图片[46]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

4. 求数组中元素的平均值

主题内容

给定一个整数数组,求平均值

代码:

图片[47]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

当心:

最后,在aver方法中计算平均值的时候,记得sum * 1.0,这样计算出来的平均值就是数据的类型。

5.在数组中查找指定元素(顺序查找)

主题内容

给定一个数组,并给定一个元素,找出该元素在数组中的位置。

代码

图片[48]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

6.在数组中查找指定元素(二分查找)

对于已排序的数组,可以使用更有效的二分查找。

什么是有序数组?

顺序分为“升序”和“降序”,如1 2 3 4,为升序。例如4 3 2 1,降序为降序。

以升序数组为例,二分查找的思路是先取中间位置的元素,看要查找的值是大于还是小于中间元素。小的话往左边找;否则,去右边找到它。

代码:

图片[49]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

二分查找的具体思路可以看我之前的博客——在有序数组中查找特定的数n(二分查找)了解详情。

7.检查数组的顺序

主题内容

给定一个整数数组,判断该数组是否排序(升序)

代码:

图片[50]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

当心:

记得检查传入的数组是否为null,如果传入的arr数组为null,则返回false类型。

8.数组排序(冒泡排序)

主题内容

给定一个数组,按升序(降序)对数组进行排序。

算法思路

每次尝试在要排序的当前范围内查找最小(或最大)元素时,将其放在数组的前面(或后面)。

代码:

图片[51]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

关于冒泡排序的详细解释可以看我之前的博客——排序算法的冒泡排序,这里就不过多介绍了。

9.数组倒序

主题内容

给定一个数组,以相反的顺序对元素进行排序。

想法

设置两个下标,分别指向第一个元素和最后一个元素。交换两个位置的元素。

然后让前一个下标自动递增,后一个下标递减,循环可以继续。

代码:

图片[52]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

五、二维数组

二维数组本质上是一维数组,只是每个元素都是一维数组。

正则二维数组

(1)二维数组的定义

图片[53]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

(2)内存中的二维数组

以上面的 int[2][3] 为例

图片[54]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

前面我们说过,二维数组本质上是一个特殊的一维数组。

这个数组的每一行arr[0]和arr[1]构成一个一维数组,每一行存储指向每一列数据的地址。

每列也是一个单独的一维数组,指向堆中的每一条数据。

(3) 打印二维数组

知道了二维数组在内存中的存储和指向,我们就知道了arr。获取行数和 arr [ i ]。获取列数。

for循环打印

我们在 for 循环中打印这个二维数据。

代码示例:

图片[55]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯@​​>

打印结果:

图片[56]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

2.for-each 打印

如果我们使用 for-each 打印,代码示例:

图片[57]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

打印结果如下:

图片[58]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

3. 工具类打印

在一个一维数组中,我们希望将数组转换为一个字符串来打印。( )。那么二维数组转字符串的工具类是什么?

如果我们用 . ( )

图片[59]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

结果打印出由 arr 行表示的数组的内容——由该列表示的一维数组的地址。明显地。( ) 不能打印二维数组的全部内容。

我们查阅了 JDK 文档并找到了 ( ) 实用程序类。

图片[60]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

功能:返回指定数组的“深层内容”的字符串表示形式。

我们使用 () 来打印…

结果如下:

图片[61]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

二维数组的内容打印成功。

( ) 可以正确打印出二维数组的所有数据。

不规则二维数组

在C语言中,我们定义一个二维数组只能定义列,而不指定行的值。

C语言中数组的定义

在Java中,我们只能定义行,列不需要指定值。

Java中不规则二维数组的定义

什么是不规则二维数组?

在前面规则的二维数组中,每一行的数据数和列数都是一样的。不规则的二维数组指定行数,列数自己确定,每行的列数自己确定。

(1)不规则二维数组的定义

图片[62]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

编译结果:

图片[63]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

首先我们指定一个有两行的二维数组

int [ ] [ ] arr = 新的 int [2] [ ];

我们自己指定数组的每一行有多少列。

arr[ 0 ] = 新的 int [ ] { 1,2,3 }

arr [ 1 ] = 新 int [ ] { 4,5 };

这是不规则二维数组的定义。

(2)内存中的二维数组

图片[64]-数组的定义与应用,你了解多少?|本次数组-4747i站长资讯

与常规的二维数组内存存储基本相同。

(3) 方式

同样,还有“三维数组”、“四维数组”等更复杂的数组,但出现的频率很低。

今天的分享已经结束,请多多包涵,指点!

文章来源:http://www.toutiao.com/a6953962692805853709/

------本页内容已结束,喜欢请分享------

感谢您的来访,获取更多精彩文章请收藏本站。

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享