在本章中,我们将了解 Java 代码中最重要的概念之一:数组。我们将看到不同数组的外观,以及如何初始化和显示它们。我们还将看一些练习,以帮助我们更好地了解数组的工作原理。
本章将介绍以下主题:
- 数组及其在 Java 程序中的使用
- 初始化数组和分配对象的方法
- 多维数组的逻辑编程
- 练习
我们可能在过去遇到过术语数组,所以让我们通过解释和示例来了解数组是什么。
数组是存储相同数据类型的多个值的容器。
在下面的示例中,我们将看到什么是容器,如何定义该容器,以及如何在其中存储值。
如果我们想使用数组,我们可以通过使用以下代码为它们分配一些空间来声明它们:
int a[] = new int[];
new
关键字基本上为该数组中的一个值分配内存。方括号表示我们正在向括号中添加多个值,[]
表示该数组的术语。为了定义一个数组,我们必须为存储在其中的多个值创建空间。在本例中,我们计划将五个整数值存储在数组中,这就是为什么我们将数组数据类型指定为整数,并且要添加的变量数在方括号中给出:
int a[] = new int[5];
正如我们在第 3 章中所观察到的,“在 Java 中处理字符串及其函数”,如果值是字符串,我们会将数组数据类型指定为String
。
我们已经声明了一个数组并为这些值分配了内存,现在我们需要传递这些值。第一个值将放在索引0
中,第二个值放在索引1
中,依此类推。索引命名从0
索引开始,因此第一个值将分配给0
索引。这意味着我们实际上初始化了数组中的值。现在,a
数组保存我们分配给它的所有值。对于我们的示例,我们为数组声明任何随机值。
现在让我们从数组中检索值。为此,我们在声明数组的值后,在main
类中键入以下代码,创建一个for
循环,然后留下一个print
语句:
for(int i=0; i<a.length;i++);
{
System.out.println(a[i]);
}
我们的起点已设置为索引0
,限制已设置为数组的长度。看看i<a.length
代码,length
是一个实际返回数组大小的方法。
在运行代码时,我们看到分配给数组的所有值都会一个接一个地打印出来。在下一节中,我们将看到一种更简单的方法来声明和初始化所有数组值。
在上一节中,我们看到了如何声明数组;最简单的方法是数组文本的形式。让我们用一个例子来解释这一点。
在上一个示例中,我们通过键入以下代码行来声明另一个数组:
int b[] = {1,4,3,5,7,8};
上一个示例中的声明与我们在本示例中执行的声明之间有什么区别?
在前面的示例中,我们分配内存,然后分配值。在本例中,我们不是分配内存,而是直接将值传递给数组。这里,内存是动态分配的,如果我们在数组声明中添加一个值,就会自动分配一个内存,并将该值传递给它。在大多数情况下,编码人员使用此方法声明数组值,而不是声明分配然后分配值。
与前面的示例类似,第一个值被分配给索引0
。如果我们编写一个类似于上一个示例的print
语句并运行代码,我们将看到显示的b
数组的值。
它包含了一维数组;让我们来谈谈多维数组。
在 x
轴和 y
轴上经过的对象只是一个多维数组。其中, x
轴为行, y
轴为矩阵的列,矩阵中给出了数组值。在这种情况下,“多”表示我们从多角透视图查看数组;这称为多维数组。以下是我们创建的多维数组,用于解释此概念:
2 4 5
3 4 7
5 2 1
这是一个矩阵,它有三行三列。2
在零行零列,旁边的4
在零行零列,其余数值迭代相同。所以每个参数都有一个 x
轴和一个 y
轴。
让我们举一个例子来解释这一点。我们将创建另一个类,将其命名为Multidimensional.java
,并在其中声明一个多维数组a
:
int a[][] = new int[2][3];
第一个括号表示 x
轴或行,第二个括号表示 y
轴或列。因此, x
轴取三个值,即三行, y
轴取三列。然后,我们为我们创建的矩阵的每个元素分配值,以解释多维数组。以下代码显示了如何为矩阵赋值:
a[0][0]=2;
a[0][1]=4;
a[0][2]=5;
a[1][0]=3;
a[1][1]=4;
a[1][2]=7;
这样,我们将把所有的值输入到一个多维数组中。如果我们想显示第二行第一列的值,我们就写一个print
语句,并给出要显示其值的元素的位置。在这种情况下,我们希望显示第二行第一列,因此print
语句将写为:
System.out.println(a[1][0]);
print
语句将显示3
,这是该位置元素的值。在下一节中,我们将举一个示例,帮助解释如何在解决编码问题时使用所有这些概念。
如何打印本例中声明的数组的所有值?在前面的示例中,我们通过简单地创建一个for
循环来打印数组,将其从0
迭代到数组的长度,然后显示数组。
如果我们想要以最简单的格式声明多维数组,比如前面的示例中如何描述数组b
,我们可以用以下方式编写它:
int b[][]= {{2,4,5},{3,4,7},{5,2,1}};
数组将假定第一个括号中的值在零索引中,第二个在第一个索引中,第三个在第二个索引中。这是声明多维数组的最简单方法。
现在我们来看看如何打印上一节中使用的整个多维数组(即a
数组)的所有值。
如果我们分析数组的声明,我们将看到需要两个for
循环来打印整个数组,一个用于行,一个用于列。
我们希望控制器扫描完整的第一行,然后是第二行,最后是第三行。因此,我们为行添加一个外部for
循环,并将长度限制设置为数组中的行数,在本例中为两行。行的外部for
循环如下所示:
for(int i=0;i<2;i++)
这个for
循环实际上会循环两次,因为我们将行的限制设置为2
。第一个循环将扫描第一行,第二个循环将扫描第二行。现在,对于每个循环,我们需要扫描该特定行中的三列。为此,我们添加了一个内部的for
循环,该循环将扫描每一列,并将限制设置为数组中的列数,在本例中为3
。列的内部for
循环将类似于以下代码:
for(int j=0;j<3;j++)
最后,为了打印数组,我们在内部for
循环中添加了一个print
语句来显示所有的值。最终代码如下:
for(int i=0;i<2;i++) //row
{
for(int j=0;j<3;j++) //coloumn
{
System.out.println(a[i][j]);
}
}
让我们试着理解我们在这里写的东西。控制将从外部for
回路启动;此外部for
循环执行两次,因为它已设置为小于2
。第一次进入外for
环后,进入内for
环;此循环执行三次,因为j
已设置为小于3
。
让我们调试一下,看看代码中的几个步骤,以便更好地理解这些循环。以下是调试代码时将执行的步骤:
-
控制器第一次执行外循环,
i
的值已初始化为0
,这意味着x
轴的值设置为0
。控制器将查看第一行,因为0
表示正在访问第一行。 -
移动到内部
for
循环并执行,j
的初始值已初始化为0
;这意味着y
轴的值被设置为0
。控制器将查看第一行和第一列,因为由于外部循环,它已经位于第一行。内部循环发送控制器查看第一列。 -
a
将第一行和第一列的值作为i
和j
的值初始化为0
、a[0][0]
。因此,此执行的输出将是第一行和第一列,在本例中为2
。 -
控制器再次移动到内部
for
循环,因为j
被迭代到1
,小于3
,循环的条件仍然满足;这意味着y
轴的值被设置为1
,它将访问第二列。控制器将查看第一行和第二列,因为它已经位于第一行,因为外环和内环发送控制器查看第二列。 -
a
将第一行和第二列的值作为i
和j
的值设置为0
和1
、a[0][1]
。因此,此执行的输出将是本例中的第一行和第二列4
。 -
控制器再次移动到内部
for
循环,因为j
被迭代到2
,小于3
,循环的条件仍然满足。这意味着y
轴的值被设置为2
,它将访问第三列。控制器将查看第一行和第三列,因为它已经位于第一行,因为外环和内环发送控制器查看第三列。 -
a
将第一行和第三列的值作为i
和j
的值设置为0
和2
、a[0][2]
。因此,此执行的输出将是第一行和第三列,在本例中为5
。 -
当控制器现在进入内部循环时,它将无法执行它,因为在
j
再次迭代后,值将为3
,这不小于我们为循环设置的限制。因此控制器退出内部for
循环,返回外部循环,迭代i
到1
的值;这意味着x
轴的值被设置为1
。控制器将查看第二行,因为1
表示正在访问第二行。 -
再次重复步骤 2、3、4、5、6 和 7,但这次将
x
轴的i
值设置为1
;这意味着将访问第二行。根据前面指定的步骤显示第二行中的所有值,直到到达矩阵的第三列。 -
控制器在访问第三列后将退出内部循环,因为
j
将迭代到3
,这小于我们为循环设置的限制。因此控制器再次退出内部for
循环并开始执行外部循环。 -
在外部
for
循环中,i
的值将被迭代到2
,循环将不会执行,因为它不小于2
,这是我们为它设置的限制。
这就是如何使用两个for
循环获得多维数组的值,其中外部循环与行一起工作,内部循环与列一起工作。
让我们尝试一些练习,帮助我们理解和使用数组。这些练习还将在面试时解释概念。
让我们为本练习创建另一个类,将其命名为InterviewMinnumber
,并在主块中定义数组。定义代码如下:
int abc[][]={{2,4,5},{3,2,7},{1,2,9}};
此代码声明了一个名为abc
的3 x 3
矩阵。现在我们需要遍历矩阵中的每个数,并寻找其中的最小数。要遍历多维数组中的每个数字,我们需要使用在“多维数组上的逻辑编程”部分中使用的相同概念。
我们在这里使用两个for
循环:一个外部for
循环遍历行,一个内部for
循环遍历列。两个for
循环代码如下所示:
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
}
}
为了找到最小的数字,我们声明了一个变量min
,并将abc
数组的第一个值赋给它。我们假设abc
矩阵中的第一个值是其中的最低值。
我们在内部for
循环中添加了一个if
循环。在这个if
循环中,无论我们写什么,都将扫描我们声明的整个矩阵中的每个元素。在if
循环中,我们添加了一个条件,检查在该实例中从矩阵中获取的值是否小于min
值。在if
循环中,我们交换min
和abc
的值。最终代码如下:
public class InterviewMinnumber
{
public static void main(String[] args)
{
int abc[][]={{2,4,5},{3,2,10},{1,2,9}};
int min=abc[0][0];
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
if(abc[i][j]<min)
{
min=abc[i][j];
}
}
}
System.out.println(min)
}
}
让我们运行代码,看看它如何找到矩阵中的最小数。
首先执行循环时,将矩阵中第一个元素的值与min
变量的值进行比较,但我们将min
变量的值设置为等于第一个元素的值,即2
。我们检查if
循环中的条件,该循环比较矩阵中元素的值和min
的值。此处,2
不小于2
,因此它不会进入循环,并再次转到代码的开头。在下一轮循环中,元素的值会发生变化,因为我们移动了矩阵中的下一个元素。现在被比较的元素是4
,我们再次检查if
条件,它不会为真,因为4
不小于2
,其中2
是min
的当前值。最后,当它到达第三行第一列中的元素1
时,if
条件为真,控制器在循环内移动并将1
分配给min
值。这一直持续到数组矩阵中的最后一个元素,abc
矩阵的每个值都与min
变量的值进行比较。
如果我们调试代码并在每一步观察它,我们将更好地理解该代码的逻辑和工作原理。
在前面的示例中,我们观察了如何从数组矩阵中打印最小的数字。在本例中,我们将查找矩阵中的最小数,然后查找同一列中的最大数。这背后的逻辑是:我们首先找到最小数,记住它所属的行号,然后在同一列中提取最大数。
让我们使用前面示例中使用的相同矩阵。我们正在使用的矩阵中此练习的输出将为4
。执行此练习将执行以下步骤:
- 在我们声明的矩阵中找到最小值
- 确定该最小数字的列
- 在标识的列中查找最大数字
在上一个示例中,我们已经执行了步骤 1,在该步骤中,我们在矩阵中找到了最小数,因此我们将在本示例中使用相同的代码,只需稍微更改变量:
int abc[][]={{2, 4, 5}, {3, 0, 7}, {1, 2, 9}}
让我们转到第 2 步。如果我们观察代码,我们会看到,i
代表行号,j
代表列号。因此,j
将取存在最小数字的列的值,我们将取这个值j
并将其分配给一个调用mincolumn
的变量。因此,我们在交换命令下编写代码,该命令将j
的值分配给mincolumn
。代码将如下所示:
mincoloumn=j;
因此,当我们在矩阵中找到最小的数字时,我们给它赋值为j
,这是mincloumn
的列数。在这种情况下,mincolumn
的值将是1
。这将处理步骤 2。
在步骤 3 中,我们从存在最小数的列中查找最大数。我们在我们创建的外部for
循环之外创建一个while
循环,以查找矩阵中的最低数量。我们将条件变量k
初始化为0
,并在每次满足while
外观条件时对其进行迭代。while
回路的条件设置为k
小于3
;这是因为我们要遍历三行,以查找其中的最大值。while
循环的代码如下所示:
while(k<3)
{
k++;
}
我们声明一个名为max
的变量,并给它一个行0
和列mincolumn
的初始值。这给变量max
一个初始值4
,因为4
是矩阵中包含最小数量的行中的第一个元素。申报代码如下:
int max=abc[0][mincoloumn];
在while
循环中,我们添加了一个if
循环,并设置了一个条件来比较列中的变量是否大于我们声明的变量max
。如果满足条件,则该数字的值被分配给max
变量,控制器在1
迭代k
后移出if
循环并返回while
查找。迭代将把控制器带到下一行,因为k
用于表示正在遍历的行,以查找最大数量。
if
循环的代码如下所示:
if(abc[k][mincoloumn]>max)
{
max=abc[k][mincoloumn];
}
因此,对于k
的第一个值,即0
,我们转到第一行和第二列,并将该值分配给max
;在本例中,值为4
。在if
条件下,我们将第一行第二列的值与max
的值进行比较。在本例中,两个值相同,因此不执行if
循环,我们迭代k
并再次进入while
循环。接下来,我们将第二行、第二列的值与max
的值进行比较;我们移动到第二行,因为k
的值被1
迭代,k
的当前值是1
。因此,在比较中,我们看到o
小于4
,其中4
是max
变量的值。再次不满足该条件,if
循环再次被跳过。第三行也是如此,max
的最终值为4
,这是列中最大的数字。最后,我们留下一个print
语句,在末尾打印max
的值。
在本练习中,我们将交换简单数组中元素的位置,并将它们按升序排列。
要做到这一点,我们首先需要理解它将如何工作的逻辑。让我们举一个例子来解释这一点。
我们启动a
数组并在其中声明值,如下代码所示:
int a[]= {2,6,1,4,9};
我们可以使用冒泡排序机制相互比较变量,然后按照我们想要的顺序放置它们。对于前面的示例,逻辑的工作方式如下:;我们将比较2
与6
、2
与1
、2
与4
以及2
与9
。比较后的最小数字是1
,我们将其位置与第一个索引交换,即2
。所以在交换之后,1
将成为新的第一个索引。这意味着1
是数组中给定值的最小数字。现在我们移动到第二个索引,第一个索引保持不变,因为我们已经比较并声明1
为固定的第一个索引,因为它是数组中最小的数字。现在我们取第二个索引值6
,并将其与数组中的其他值进行比较。首先我们比较6
和2
,由于2
比6
小,我们交换了它们的位置,所以2
是新的第一个指数,6
是第二个指数。然后比较2
和3
;基本上,我们将第一个索引与数组中的所有其他值进行比较。然后比较2
与3
、2
与4
、2
与9
;这里2
是最小的数字。所以2
成为数组中固定的第二个索引。现在我们剩下四个需要排序的值。我们再次将6
与其他值进行比较。6
比3
小,所以我们交换了6
和3
的位置。这使得3
成为数组中的第三个索引,我们将3
与其他数字进行比较,3
是其中给出的所有值中最小的。所以3
成为我们在数组中固定的第三个索引。然后,我们对最后三个值执行相同的操作,并得出结论,最终排列为1
、2
、3
、4
、6
、9
。现在我们需要在 Java 程序中应用这个逻辑并打印它。
我们将为我们的逻辑决定一个算法,并基于该算法,我们将逐步设计我们的代码。我们将编写一个外部for
循环,移动一个索引并将其与其他索引进行比较。
我们编写一个外部for
循环,并将条件设置为不跨越数组的长度;此处数组大小为5
,因此条件设置为i
,小于5
。如果i
为0
,变量值将与第一、第二、第三和第四个变量进行比较。如果i
是2
,变量会将其与第三个和第四个变量进行比较。因此无论i
索引是什么,它都应该开始将i
的值与其下一个索引进行比较。为此,我们将创建一个内部for
循环,并将j
初始化为始终比i
、i
多一个数字加上1
,因为我们会将其与下一个指数进行比较。所以,如果i
等于0
,则j
将为1
。所以零索引将从第一个索引开始比较。我们比较它直到数组结束,所以我们将内部for
循环的限制设置为j
,因为它小于数组的长度,在本例中为5
。
然后,我们在内部for
循环中添加一个if
循环。这个循环将在索引之间进行比较,并在满足条件时交换值。第一轮比较完成后,控制器退出内部for
循环,返回外部for
循环,即在比较后选取最小的数字,推到角落,索引移动到下一个值。
现在我们回到if
循环中,编写代码,在比较条件为真时交换值。要交换变量值,我们需要声明一个temp
变量并将a[i]
编号分配给temp
。我们添加以下代码以成功交换变量:
temp=a[i];
a[i]=a[j];
a[j]=temp;
最后,我们添加一个print
语句来显示比较和重新排列值后的最终数组。
最终输出将显示如下:
1
2
4
6
9
在本章中,我们介绍了数组中的各种概念。我们研究了不同类型的数组,以及如何初始化和显示它们。然后,我们进行了不同的练习,以了解如何在不同的实例中使用数组。
在下一章中,我们将讨论为什么Date
类和构造函数是 Java 的重要组成部分