你好!以前,在训练期间,我们使用单个对象(或原始类型)。但是,如果我们需要处理的不是一个对象,而是整个组怎么办?例如,我们想要创建公司所有员工的生日列表。例如,它应包含 30 行,格式为:“Andrey Petrov,1 月 25 日。” 一个特殊的数据结构,即数组,将在这方面为我们提供帮助。如果将数组与现实生活中的物体进行比较,它的结构与带有单元的银行金库非常相似: 数组也由单元组成。您可以在每个单元格中放置一些东西。在这种情况下,要访问内容,您需要知道手机号码。数组是这样创建的:
public class Main {
public static void main(String[] args) {
String [] birthdays = new String[10]; // array of Java strings
}
}
这里我们创建了一个包含 10 个单元格的数组。 您可以立即关注该阵列的一些功能:
- 它存储严格定义类型的数据。如果我们最初创建了一个字符串数组
String
,我们将无法在其中存储任何其他内容。数据类型在创建数组时指定。这就是它与保险箱的区别,客户可以在保险箱中存储他想要的任何东西。 - 数组可以存储基本类型(例如
int
)、字符串(String
)或同一类的对象的数据。更准确地说,甚至不是对象本身,而是这些对象的链接。 - 数组的大小必须在创建时指定。创建后您将无法稍后指定它或调整它的大小。
[]
Java 表示通过在表达式两侧使用方括号来创建数组。它们可以在引用变量的名称之前或之后指定 - 无论哪种方式都可以:
//Java arrays of strings, two syntaxes
String [] birthdays = new String[10];
String birthdays [] = new String[10];
如果要将某些内容写入数组,则需要指定要写入该值的单元格的编号。数组单元编号从 0 开始。从零开始是编程中的常见做法。你越快习惯它就越好:) 也就是说,如果你想在数组的第一个单元格中放入一些值,可以像这样完成:
public class Main {
public static void main(String[] args) {
String birthdays [] = new String[10];
birthdays[0] = "Lena Eliseeva, March 12";
}
}
现在,数组的第一个单元格包含同事的生日,其中包含一个包含 Lena 生日的字符串。以此类推,可以添加其他值:
public class Main {
public static void main(String[] args) {
String birthdays [] = new String[10];
birthdays[0] = "Lena Eliseeva, March 12";
birthdays[1] = "Kolya Romanov, May 18";
birthdays[7] = "Olesya Ostapenko, January 3";
}
}
请注意:我们将 Olesya 的生日添加到第八个单元格中(您是否忘记了为什么 7 号单元格是第八个单元格?)。尽管所有其他单元格均未填充。没有必要将值按顺序写入数组 - 没有这样的限制。另一方面,如果按顺序写入,则可以更轻松地跟踪空闲和占用单元的数量,并且数组中不会留下“洞”。如果您想获取数组单元格的内容(如银行单元格的情况),您需要知道它的编号。这是这样完成的:
public class Main {
public static void main(String[] args) {
String birthdays [] = new String[10];
birthdays[0] = "Lena Eliseeva, March 12";
birthdays[1] = "Kolya Romanov, May 18";
birthdays[7] = "Olesya Ostapenko, January 3";
String olesyaBirthday = birthdays[7];
System.out.println(olesyaBirthday);
}
}
控制台输出:
Олеся Остапенко, 3 января
我们创建了一个变量String
并告诉编译器:“在数组中查找索引为 7 的单元格birthdays
,并将存储在那里的值赋给变量String
olesyaBirthday
。” 他正是这么做的。
Java数组长度
使用数组时,您可以使用特殊属性 - 轻松找出其长度length
。
public class Main {
public static void main(String[] args) {
String birthdays [] = new String[10];
birthdays[0] = "Lena Eliseeva, March 12";
birthdays[1] = "Kolya Romanov, May 18";
birthdays[7] = "Olesya Ostapenko, January 3";
int birthdaysLength = birthdays.length;
System.out.println(birthdaysLength);
}
}
控制台输出:
10
笔记:该属性length
存储数组的大小,而不是填充单元格的数量。我们的数组只存储3个值,但是当我们创建它时,我们为其指定了size = 10。这就是该字段返回的值length
。为什么这可能有用?举例来说,如果您想将所有生日的列表打印到控制台(以检查没有人被遗忘),您可以通过一个简单的循环来完成此操作:
public class Main {
public static void main(String[] args) {
String birthdays [] = new String[10];
birthdays[0] = "Lena Eliseeva, March 12";
birthdays[1] = "Kolya Romanov, May 18";
birthdays[2] = "Vika Ignatova, July 12";
birthdays[3] = "Denis Kozlov, September 7";
birthdays[4] = "Maxim Maslennikov, November 9";
birthdays[5] = "Roman Baranov, August 14";
birthdays[6] = "Valery Pyatkina, April 1";
birthdays[7] = "Olesya Ostapenko, January 3";
birthdays[8] = "Kostya Gurko, October 19";
birthdays[9] = "Seryozha Naumov, 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
例如,可以像这样创建 一个数字数组:
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
Java 对象数组
您已经听说过对象数组和基元数组在内存中的存储方式不同。我们以一个包含三个对象的数组为例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("Hippopotamus");
cats[2] = new Cat("Philip Markovich");
}
}
这里有几点需要理解:
- 就原语而言,Java 数组存储许多特定值(例如数字
int
)。对于对象,数组存储许多引用。该数组cats
由三个单元组成,每个单元都包含对对象的引用Cat
。每个链接都指向内存中存储该对象的地址。 - 数组元素存储在内存中的单个块中。这样做是为了更有效、更快速地访问它们。因此,链接
cats
指向内存中的一个块,其中存储了所有对象(数组的元素)。Acats[0]
- 到该块内的特定地址。
数组的数组或二维数组
基于此,我们面临一个问题——例如,我们是否可以创建一个数组数组,而不是字符串或数字数组?答案是——是的,我们可以!数组可以存储其中的任何对象,包括其他数组。这样的数组称为二维数组。如果你用图片来描绘它,它看起来和普通的桌子非常相似。例如,我们想要创建一个数组来存储 3 个数字数组,int
每个数组有 10 个单元格。它看起来像这样: 每行代表一个数字数组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("Fluff");
}
[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]);
}
}
在外层循环(variable 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}};
通常,我们会将二维数组写numbers
为int[3][3]
,但此方法允许我们立即指定值。为什么需要二维数组?举例来说,在它的帮助下,您可以轻松地重新创建著名的游戏“战舰”: “战舰”中的比赛场地结构可以轻松描述:一个由 10 个数组组成的二维数组,每个数组有 10 个单元格。您为自己和对手创建两个这样的数组:
int [][] seaBattle = new int[10][10];
int [][] seaBattle2 = new int[10][10];
*
你在你的船只所在的单元格中 填写一些值(例如数字或符号),然后你和你的对手轮流调用单元格编号:
- 海战[6][5]!
- 过去的!海战2[6][6]!
- 受伤了!
- 海战2[6][7]!
- 受伤了!
- 海战2[6][8]!,
- 被杀了!
有关数组的其他资源
想了解更多关于数组的知识吗?请看看下面的文章。关于这个主题有很多有趣且有用的信息。- Java 中的数组- 一篇有关数组、数组的创建、初始化和使用的详细文章。并举例说明。
- Arrays类及其使用 ——文章介绍了该类的一些方法
Array
- 数组是第一个专门讨论数组的 JavaRush 讲座。
- 多维数组- 有关多维数组的详细文章和示例。
- 返回零长度数组,而不是 null - 《高效编程》作者 Joshua Bloch 谈论如何更好地返回空数组。
GO TO FULL VERSION