CodeGym /Java 博客 /随机的 /关于数组的一些事
John Squirrels
第 41 级
San Francisco

关于数组的一些事

已在 随机的 群组中发布
你好!之前在您的培训中,我们使用过单个对象(和原始类型)。但是,如果我们需要处理一整组对象而不是一个对象怎么办?例如,假设我们要创建我们公司所有员工的生日列表。它应该包含 30 个字符串,格式如下:"Sarah Huffman, January 25" 我们将从称为数组的特殊数据结构中获益。如果我们将数组比作一个真实的对象,它非常类似于带有保险箱的银行金库: 关于数组的一些事 - 1数组也由“盒子”组成。你可以在每个盒子里放一些东西(一个元素)。要访问一个元素,您需要知道它的框号(索引)。这是创建数组的方式:

public class Main {

   public static void main(String[] args) {

       String [] birthdays = new String[10];
      
   }
}
这里我们创建了一个包含 10 个元素的数组。 您可以立即注意到数组的一些特征:
  1. 它存储定义明确的数据类型的元素。如果我们创建一个 String 数组,我们就不能在其中存储任何其他内容。数据类型是在创建数组时指定的。这是它与保险箱(客户可以在其中存放他或她想要的东西)的不同之处。

  2. 它的大小必须在创建数组时指定。您不能稍后指示它或在创建数组后更改其大小
我们正在创建数组这一事实由表达式两边的方括号指示。它们可以在引用变量名称之前或之后指定。无论哪种方式都有效:

String [] birthdays = new String[10];
String birthdays [] = new String[10];
如果要将内容写入数组,则需要指定要写入值的框的索引。数组中的框从 0 开始编号。 从零开始计数是编程中非常常见的做法。你越快习惯它越好 :) 关于数组的一些事 - 2这意味着,如果你想在第一个盒子里放一些值,你可以这样做:

public class Main {

   public static void main(String[] args) {

       String birthdays [] = new String[10];
       birthdays[0] = "Jana Russell, March 12";
   }
}
现在 Jana 的生日存储在我们的员工生日数组的第一个单元格中:您可以以类似的方式添加其他值:

public class Main {

   public static void main(String[] args) {

       String birthdays [] = new String[10];
       birthdays[0] = "Jana Russell, March 12";
       birthdays[1] = "Landon Chan, May 18";
       birthdays[7] = "Rosie Mills, January 3";
   }
}
请注意,我们在第八个盒子中添加了 Rosie 的生日(你不会忘记为什么 7 号盒子是第八个盒子吧?)。您可以看到我们还没有填充所有其他单元格。我们不必按顺序将值写入数组。没有这样的要求。当然,按顺序编写元素可以更容易地跟踪有多少盒子是空闲的,有多少盒子被占用,并且它可以防止数组出现“漏洞”。如果你想得到其中一个盒子里的东西,那么(就像保险箱一样)你需要知道它的号码。这是如何完成的:

public class Main {

   public static void main(String[] args) {

       String birthdays [] = new String[10];
       birthdays[0] = "Jana Russell, March 12";
       birthdays[1] = "Landon Chan, May 18";
       birthdays[7] = "Rosie Mills, January 3";

       String rosieBirthday = birthdays[7];
       System.out.println(rosieBirthday);
   }
}
控制台输出: Rosie Mills,1 月 3 日 我们创建了一个变量并告诉编译器:“在birthdaysString数组中找到索引为 7 的框,并将其中包含的值分配给变量rosieBirthday 。这正是它所做的。使用数组时,我们可以使用特殊属性轻松找到它们的长度:lengthString

public class Main {

   public static void main(String[] args) {

       String birthdays [] = new String[10];
       birthdays[0] = "Jana Russell, March 12";
       birthdays[1] = "Landon Chan, May 18";
       birthdays[7] = "Rosie Mills, January 3";

       int birthdaysLength = birthdays.length;
       System.out.println(birthdaysLength);
   }
}
控制台输出: 10 注意:该length属性存储的是数组大小,而不是已满的框数。我们的数组只存储 3 个值,但我们在创建它时将其大小指定为 10。这正是该字段返回的值length。为什么这会派上用场?好吧,假设您想显示所有生日的列表(以验证没有人被遗忘)。您可以在一个简单的循环中执行此操作:

public class Main {

   public static void main(String[] args) {

       String birthdays [] = new String[10];
       birthdays[0] = "Jana Russell, March 12";
       birthdays[1] = "Landon Chan, May 18";
       birthdays[2] = "Jeremiah Leonard, July 12";
       birthdays [3] = "Kenny Russo, September 7";
       birthdays[4] = "Tommie Barnes, November 9";
       birthdays [5] = "Roman Baranov, August 14";
       birthdays [6] = "Chanice Andersen, April 1";
       birthdays[7] = "Rosie Mills, January 3";
       birthdays [8] = "Keenan West, October 19";
       birthdays [9] = "Abraham McArthur, May 3";

       for (int i = 0; i < birthdays.length; i++) {
           System.out.println(birthdays[i]);
       }
   }
}
在循环中,我们声明变量i,它被初始化为零。每次通过时,我们都会从数组中获取索引为 i 的元素并显示其值。循环将执行 10 次迭代,并且 i 将从 0 增加到 9——数字恰好是我们数组元素的索引!因此,我们将显示从birthdays[0]birthdays[9] 的所有值 。实际上,还有另一种创建数组的方法。例如,您可以int像这样创建一个 s 数组:

public class Main {

   public static void main(String[] args) {
       int numbers [] = {7, 12, 8, 4, 33, 79, 1, 16, 2};
   }
}
这种技术称为“快捷方式初始化”。这非常方便,因为我们同时创建了一个数组并用值填充它。我们不必明确指定数组大小:通过快捷方式初始化,该length字段会自动设置。

public class Main {

   public static void main(String[] args) {
       int numbers [] = {7, 12, 8, 4, 33, 79, 1, 16, 2};
       System.out.println(numbers.length);
   }
}
控制台输出: 9 现在,稍微介绍一下数组是如何存储在内存中的。假设我们有一个包含三个Cat对象的数组:

public class Cat {

   private String name;

   public Cat(String name) {
       this.name = name;
   }

   public static void main(String[] args) {

       Cat[] cats = new Cat[3];
       cats[0] = new Cat("Thomas");
       cats[1] = new Cat("Behemoth");
       cats[2] = new Cat("Lionel Messi");
   }
}
你需要在这里了解一些事情:
  1. 在基元的情况下,数组存储一组特定值(例如ints)。对于对象,数组存储一组引用
    cats数组由三个元素组成,每个元素都是对一个对象的引用Cat。每个引用都指向存储相应对象的内存地址。

  2. 数组元素排列在内存中的单个块中。这样做是为了能够快速有效地访问它们。
因此,cats引用存储所有对象(数组元素)的内存块。Cats[0]引用此块中的特定地址。 关于数组的一些事 - 3 理解数组不仅仅是存储对象很重要:它本身就是一个对象。 这让我们质疑我们是否不仅可以创建字符串数组或数字数组,还可以创建数组数组。答案是肯定的,我们可以!数组可以存储任何对象,包括其他数组。这样的数组称为二维数组。如果我们用视觉来表示它,它会非常类似于一张普通的桌子。假设,我们要创建一个包含3 个数组的数组,每个数组可以存储 10int个。它看起来像这样:
关于数组的一些事 - 4
每行代表一个int数组。第一个数组包含从 1 到 10 的数字,第二个数组 - 从 -1 到 -10,第三个 - 一组随机数。这些数组中的每一个都存储在我们的二维数组的盒子中。在代码中,二维数组的初始化如下所示:

public static void main(String[] args) {
   Cat[][] cats = new Cat[3][5];
}
我们的二维数组cats存储了3 个数组,每个数组有 5 个盒子。如果我们想把一个对象放在第二个数组的第三个盒子里,我们会这样做:

public static void main(String[] args) {
   Cat[][] cats = new Cat[3][5];
   cats[1][2] = new Cat("Fluffy");
}
[1]指示第二个数组,并[2]指示该数组的第三个框。因为二维数组由多个数组组成,为了遍历它并显示它的所有值(或填充它的所有元素),我们需要一个嵌套循环:

for (int i = 0; i < cats.length; i++) {
   for (int j = 0; j < cats[i].length; j++) {
       System.out.println(cats[i][j]);
   }
}
在外部循环(变量i)中,我们遍历二维数组中的所有数组。在内部循环(变量j)中,我们遍历每个数组的所有元素。结果,cats[0][0](第一个数组,第一个元素)将首先显示,然后是cats[0][1](第一个数组,第二个元素)。在我们完成第一个数组后,我们将显示cats[1][0]cats[1][1]cats[1][2]等。顺便说一句,二维数组也支持速记初始化:

int[][] numbers = {{1,2,3}, {4,5,6}, {7,8,9}};
通常,我们会将二维数组声明numbersint[3][3],但这种简写让我们可以立即指定值。为什么需要二维数组?好吧,您可以使用它来轻松地重现著名的“战舰”游戏: 关于数组的一些事 - 5 在“战舰”中,比赛场地的结构可以很容易地描述:一个由 10 个数组组成的二维数组,每个数组有 10 个元素。你创建两个这样的阵列(一个给你,一个给你的对手)

int[][] battleshipBoard1 = new int[10][10];
int[][] battleshipBoard2 = new int[10][10];
使用一些值(例如数字或符号)来填充与您的船只位置相对应的元素,然后轮流调用特定元素的坐标:
  • battleshipBoard1[0][2]!
  • 错过!battleshipBoard2[2][4]!
  • 打!
  • battleshipBoard2[2][5]!
  • 打!
  • battleshipBoard2[2][6]!,
  • 沉没!
我们对数组的第一次介绍到此结束,但这只是我们与它们交互的开始。在接下来的课程中,我们将看到它们的有趣使用方式,并了解 Java 有哪些内置函数可以让我们更方便地使用这种数据结构:)
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION