Skip to content

Latest commit

 

History

History
317 lines (214 loc) · 20.1 KB

File metadata and controls

317 lines (214 loc) · 20.1 KB

六、了解有关数组的所有信息

在本章中,我们将了解 Java 代码中最重要的概念之一:数组。我们将看到不同数组的外观,以及如何初始化和显示它们。我们还将看一些练习,以帮助我们更好地了解数组的工作原理。

本章将介绍以下主题:

  • 数组及其在 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

让我们调试一下,看看代码中的几个步骤,以便更好地理解这些循环。以下是调试代码时将执行的步骤:

  1. 控制器第一次执行外循环,i的值已初始化为0,这意味着 x 轴的值设置为0。控制器将查看第一行,因为0表示正在访问第一行。

  2. 移动到内部for循环并执行,j的初始值已初始化为0;这意味着 y 轴的值被设置为0。控制器将查看第一行和第一列,因为由于外部循环,它已经位于第一行。内部循环发送控制器查看第一列。

  3. a将第一行和第一列的值作为ij的值初始化为0a[0][0]。因此,此执行的输出将是第一行和第一列,在本例中为2

  4. 控制器再次移动到内部for循环,因为j被迭代到1,小于3,循环的条件仍然满足;这意味着 y 轴的值被设置为1,它将访问第二列。控制器将查看第一行和第二列,因为它已经位于第一行,因为外环和内环发送控制器查看第二列。

  5. a将第一行和第二列的值作为ij的值设置为01a[0][1]。因此,此执行的输出将是本例中的第一行和第二列4

  6. 控制器再次移动到内部for循环,因为j被迭代到2,小于3,循环的条件仍然满足。这意味着 y 轴的值被设置为2,它将访问第三列。控制器将查看第一行和第三列,因为它已经位于第一行,因为外环和内环发送控制器查看第三列。

  7. a将第一行和第三列的值作为ij的值设置为02a[0][2]。因此,此执行的输出将是第一行和第三列,在本例中为5

  8. 当控制器现在进入内部循环时,它将无法执行它,因为在j再次迭代后,值将为3,这不小于我们为循环设置的限制。因此控制器退出内部for循环,返回外部循环,迭代i1的值;这意味着 x 轴的值被设置为1。控制器将查看第二行,因为1表示正在访问第二行。

  9. 再次重复步骤 2、3、4、5、6 和 7,但这次将 x 轴的i值设置为1;这意味着将访问第二行。根据前面指定的步骤显示第二行中的所有值,直到到达矩阵的第三列。

  10. 控制器在访问第三列后将退出内部循环,因为j将迭代到3,这小于我们为循环设置的限制。因此控制器再次退出内部for循环并开始执行外部循环。

  11. 在外部for循环中,i的值将被迭代到2,循环将不会执行,因为它不小于2,这是我们为它设置的限制。

这就是如何使用两个for循环获得多维数组的值,其中外部循环与行一起工作,内部循环与列一起工作。

练习

让我们尝试一些练习,帮助我们理解和使用数组。这些练习还将在面试时解释概念。

打印3 x 3矩阵中的最小数字

让我们为本练习创建另一个类,将其命名为InterviewMinnumber,并在主块中定义数组。定义代码如下:

int abc[][]={{2,4,5},{3,2,7},{1,2,9}};

此代码声明了一个名为abc3 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循环中,我们交换minabc的值。最终代码如下:

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,其中2min的当前值。最后,当它到达第三行第一列中的元素1时,if条件为真,控制器在循环内移动并将1分配给min值。这一直持续到数组矩阵中的最后一个元素,abc矩阵的每个值都与min变量的值进行比较。

如果我们调试代码并在每一步观察它,我们将更好地理解该代码的逻辑和工作原理。

显示具有最小数字的列中的最大数字

在前面的示例中,我们观察了如何从数组矩阵中打印最小的数字。在本例中,我们将查找矩阵中的最小数,然后查找同一列中的最大数。这背后的逻辑是:我们首先找到最小数,记住它所属的行号,然后在同一列中提取最大数。

让我们使用前面示例中使用的相同矩阵。我们正在使用的矩阵中此练习的输出将为4。执行此练习将执行以下步骤:

  1. 在我们声明的矩阵中找到最小值
  2. 确定该最小数字的列
  3. 在标识的列中查找最大数字

在上一个示例中,我们已经执行了步骤 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,其中4max变量的值。再次不满足该条件,if循环再次被跳过。第三行也是如此,max的最终值为4,这是列中最大的数字。最后,我们留下一个print语句,在末尾打印max的值。

使用/不使用临时变量交换变量

在本练习中,我们将交换简单数组中元素的位置,并将它们按升序排列。

要做到这一点,我们首先需要理解它将如何工作的逻辑。让我们举一个例子来解释这一点。

我们启动a数组并在其中声明值,如下代码所示:

int a[]= {2,6,1,4,9};

我们可以使用冒泡排序机制相互比较变量,然后按照我们想要的顺序放置它们。对于前面的示例,逻辑的工作方式如下:;我们将比较262124以及29。比较后的最小数字是1,我们将其位置与第一个索引交换,即2。所以在交换之后,1将成为新的第一个索引。这意味着1是数组中给定值的最小数字。现在我们移动到第二个索引,第一个索引保持不变,因为我们已经比较并声明1为固定的第一个索引,因为它是数组中最小的数字。现在我们取第二个索引值6,并将其与数组中的其他值进行比较。首先我们比较62,由于26小,我们交换了它们的位置,所以2是新的第一个指数,6是第二个指数。然后比较23;基本上,我们将第一个索引与数组中的所有其他值进行比较。然后比较232429;这里2是最小的数字。所以2成为数组中固定的第二个索引。现在我们剩下四个需要排序的值。我们再次将6与其他值进行比较。63小,所以我们交换了63的位置。这使得3成为数组中的第三个索引,我们将3与其他数字进行比较,3是其中给出的所有值中最小的。所以3成为我们在数组中固定的第三个索引。然后,我们对最后三个值执行相同的操作,并得出结论,最终排列为123469。现在我们需要在 Java 程序中应用这个逻辑并打印它。

我们将为我们的逻辑决定一个算法,并基于该算法,我们将逐步设计我们的代码。我们将编写一个外部for循环,移动一个索引并将其与其他索引进行比较。

我们编写一个外部for循环,并将条件设置为不跨越数组的长度;此处数组大小为5,因此条件设置为i,小于5。如果i0,变量值将与第一、第二、第三和第四个变量进行比较。如果i2,变量会将其与第三个和第四个变量进行比较。因此无论i索引是什么,它都应该开始将i的值与其下一个索引进行比较。为此,我们将创建一个内部for循环,并将j初始化为始终比ii多一个数字加上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 的重要组成部分