如何在Java中使用数组

如何在Java中使用数组

介绍

一个数组允许你将多个元素分组并存储起来。使用数组,你可以存储任何类型的数据,即引用类型或原始类型。然而,所有的数组元素必须是相同的数据类型。数组的数据类型在创建数组时声明,不能更改。同样,数组的长度—即它可以存储多少元素—在开始时就被定义好,不能更改。

在Java中,数组发挥着基础作用,因为许多核心数据类型都是基于它们构建的。例如,经常使用的引用类型String实际上是以char元素的数组实现的。因此,即使你可能不知道,你已经使用过数组。

在本教程中,您将使用char数组来安全存储密码。这是数组的常见用例。与String相比,char数组是存储密码的更好选择,因为String对象是不可变的,即无法被覆盖。所以即使您可能不再需要一个密码String对象,也不能随意丢弃它。这意味着对象仍然存在于内存中,因此攻击者理论上可以访问内存的这一部分并读取密码。相比之下,您可以轻松覆盖存储为char数组的密码并使其无法使用。因此,攻击者无法通过检查内存来学习密码。

先决条件

要完成本教程,您需要:

一个可以执行Java程序并跟随示例进行的环境。要在您的本地机器上设置这个环境,您将需要以下内容:

Java(版本11或更高)已安装在您的计算机上,并且使用Java开发工具包(JDK)提供的编译器。对于Ubuntu和Debian,您可以按照我们的教程《在Ubuntu 22.04上使用Apt安装Java》中的选项1的步骤进行操作。对于其他操作系统,包括Mac和Windows,请按照Java安装的下载选项进行操作。

为了编译和运行代码示例,本教程使用Java Shell,这是一个从命令行运行的Read-Evaluate-Print Loop(REPL)。要开始使用JShell,请查看JShell介绍指南。为了避免冗余的指令,所有示例都在一个JShell会话中执行,并使用相同的变量。

熟悉Java和面向对象编程,您可以在我们的教程《如何在Java中编写您的第一个程序》中找到。

对Java数据类型的理解,在我们的教程中讨论了理解Java中的数据类型。

创建数组

要开始使用数组,首先必须创建它。有几种创建数组的方法,你创建数组的方式取决于你是否知道数组将要保存的元素。

信息: 要跟随本教程中的示例代码,通过运行jshell命令在本地系统上打开Java Shell工具。然后,你可以通过在jshell>提示后添加示例代码并按ENTER键来复制、粘贴或编辑示例代码。要退出jshell,请输入/exit。

如果你不知道数组元素,那么可以创建一个空数组并定义其大小,如下所示:

char[] password = new char[6];

在char关键字后面的组合[]将变量password定义为数组。char关键字表示变量保存char原始数据类型。 要创建数组对象,你可以使用new关键字,并将数组定义为char[6],这意味着它是一个包含char原始数据类型并且包含六个元素的数组。

当你运行上述代码时,将会收到以下输出:

password ==> char[6] { '\000', '\000', '\000', '\000', '\000', '\000' }

输出确认已经创建了一个名为password的新char数组。它可以存储六个元素([6]),目前为空(\000)。

或者,如果您已经知道数组元素,可以像这样创建一个名为password的char元素数组:

char[] password = new char[] {'s', 'e', 'c', 'r', 'e', 't'};

语句的左侧,在等号之前部分,与第一个空数组示例中的左侧部分相同——一个名为password的char数组被定义。语句的第二部分,在等号之后,再次以new关键字开始;然而,元素的数量并没有明确给出。相反,列出了所有六个元素。列表以一个左括号开头,接着是六个元素。因为元素是char原语,它们被单引号(')包围。列表以一个右括号结尾。

当您将上述代码粘贴到jshell中时,您将会得到以下输出:

Outputpassword ==> char[6] { 's', 'e', 'c', 'r', 'e', 't' }

输出确认passwordchar数组已经被创建,并且其元素已列出。

在后一个示例中,您在创建数组时指定了元素。这样做可以避免编写额外的指令来为元素分配值。这就是以这种方式创建数组的好处。或者,您可以创建代码来为每个新定义的元素填充元素。接下来您将这样做。

指定和更改数组元素

您并不总是知道数组的元素,因此,在创建数组时指定它们可能不是一个选择。无论如何,无论您最初是否已经指定了数组元素,您始终可以随时指定或更改它们。

例如,您可以通过引用其索引(即数组中的位置)来更改password数组的一个元素,如下所示:

password[0] = 'n';

通过使用password[0],您正在引用password数组的第一个元素。数组元素从0开始编号,因此第一个元素的索引将为0,就像这种情况一样。数组元素索引号始终在方括号[]之间指定。您重新定义数组元素并为其分配一个新值——'n' char基元。

在jshell中执行前述语句后,您将获得类似以下的输出:

Output$8 ==> 'n'

临时变量$8在jshell内部使用。在您的情况下,它可能是一个不同的数字。

在jshell中有一个独特的功能,您可以使用它来确认password数组是否按照您的意图更改。当您在jshell中粘贴数组的名称(在这种情况下为password)时,它将打印数组及其元素,无需额外的方法:

password

在jshell中,您将获得以下输出:

Outputpassword ==> char[6] { 'n', 'e', 'c', 'r', 'e', 't' }

此输出确认您已成功将password char数组从s、e、c、r、e、t更改为n、e、c、r、e、t。现在,如果攻击者获取了对您服务器的访问权限,他们将获得更改后的密码而不是原始密码。或者,如果您使用String变量来存储密码,旧值对象将在一段时间内仍然存在于内存中,即使您为其重新分配一个新值,攻击者也可以读取它。

您将在本教程中继续使用password数组,因此出于一致性原因,请通过再次引用它并在jshell中执行命令来将第一个元素的值恢复为s:

password[0] = 's';

这将产生类似于先前输出的输出,其中包含一个临时变量,例如$25,这证实了更改是成功的:

Output$25 ==> 's'

您再次拥有包含元素's', 'e', 'c', 'r', 'e', 't'的原始password数组。现在您知道如何创建和修改数组的元素,是时候开始阅读并使用其元素了。

获取数组元素

当获取特定数组元素时,您将使用其索引。例如,要获取password数组的第二个元素,您可以使用以下代码:

System.out.println(password[1]);

在此代码中,您使用println()方法打印password数组的第二个元素。(有关System.out.println语句的更多信息,请查看我们的教程如何在Java中编写您的第一个程序。)第二个元素的索引为1,因为数组元素从0开始编号,如前所述。

此代码将产生以下输出:

Outpute

输出打印第二个数组元素e。与打印一样,您可以在任何其他需要char值的地方使用它。

此外,您还可以使用foreach循环迭代所有数组元素,如我们的教程如何在Java中使用循环中所述。循环是一种控制重复程序流程的结构,foreach循环特别适用于遍历数组,因为它需要最少的样板代码。以下是一个示例:

for (char c : password) {

System.out.print(c);

}

这个`foreach`循环遍历`password`数组,并使用临时的`char`变量称为`c`。每次迭代中,`c`从`password`数组的第一个元素移动到最后一个元素。一旦`c`获得数组元素的值,您可以在代码块内以任何合适的方式使用`c`。在前面的例子中,您使用`print()`方法打印`c`。

请注意,`print()`方法打印一个没有换行符的参数。相比之下,在到目前为止的教程中,您已经使用了`println()`方法,每次运行时都会留下一个新行。在这种情况下,`print()`更适合,因为它会在同一行上打印来自`password`数组的所有元素,结果将更好地可视化为单个单词(“secret”)。

如果您精确地按照前面的步骤执行并在`jshell`中运行此代码,您将获得以下输出:

Outputsecret

如果您错过了将第一个数组元素从`n`重置回`s`的步骤,您将得到`necret`而不是`secret`。

当您结合到目前为止构建的知识时,可以获取数组的所有元素。从这一点开始,您准备深入研究数组的主题,并学习执行各种功能的有用数组方法。

使用数组方法

Java在`java.util`包中有一个非常有帮助的`Arrays`类。这个类在处理数组时为你提供了一些常见用例的实用方法,这意味着你不必重复造轮子,可以节省冗余的努力。以下是一些最常用的方法:

equals()方法

`equals()`方法用于比较两个数组,以确定它们是否相等。为了使两个数组相等,它们必须具有相同的长度、元素和顺序。继续使用`password`数组示例,你将创建一个名为`password2`的第二个数组,其中包含字符`n`,`o`,`n`和`e`:

char[] password2 = new char[] {'n', 'o', 'n', 'e'};

在`jshell`中运行此代码后,你将获得以下确认:

Outputpassword2 ==> char[4] { 'n', 'o', 'n', 'e' }

前面的输出证实了你有`password2`数组。它有四个元素,它们也被打印出来。如果你没有退出之前的`jshell`会话,你还将拥有原始的`password`数组。如果你已经退出了`jshell`会话,你将不得不使用创建数组中的步骤重新创建`password`数组,以便你有两个可以比较的数组。

现在你可以像这样比较这两个数组:

System.out.println(Arrays.equals(password, password2));

在前一行中,您正在使用println()方法打印来自Array.equal()方法比较password和password2数组的结果。

由于这两个数组不同,结果将是false:

Outputfalse

输出false确认了这两个数组不相等。作为练习,创建其他数组并进行比较。如果两个数组相等,您将获得true结果。

sort()方法

sort()方法按升序对数组元素进行排序。使用这种方法,您可以通过运行以下命令将password数组中的字符按字母顺序排列:

Arrays.sort(password);

之后,您可以仅通过在jshell中输入数组名称来打印数组,以记录它的变化,就像这样:

password;

jshell的输出将为:

Outputpassword ==> char[6] { 'c', 'e', 'e', 'r', 's', 't' }

这证实了数组仍然具有相同的元素,但它们的顺序已经改变。数组元素从's','e','c','r','e','t'重新排序为'c','e','e','r','s','t'。像password这样的情况下,改变数组的顺序可能不是一个好主意,因为原始顺序可能很重要。如果更改顺序,密码将与原始密码不同,并且无法使用。但是,在其他用例中,数组元素的顺序可能并不重要,并且可能需要进行初始排序,正如您将在接下来看到的。

binarySearch()方法

binarySearch()方法搜索数组的元素以查找给定值。该方法的一个特点是,它要求首先对数组元素进行排序;否则,您将获得意外的结果。因此,一旦对password数组进行了排序,您就可以找到元素的索引。例如,您可以找出字符c在password中的索引并打印出来,像这样:

System.out.println(Arrays.binarySearch(password, 'c'));

这将产生:

Output0

请记住,password数组现在已经排序,并且看起来像这样:'c','e','e','r','s','t'。由于打印了数字0,这意味着字符'c'的索引为0,因为它是第一个数组元素。

copyOf() 方法

copyOf() 方法用于在需要增加或减小数组大小时将给定数组复制到一个新数组中。由于数组创建后其长度无法更改,您可以使用此方法创建一个具有所需大小的新数组,其中包含从旧数组复制的内容。

例如,password 数组只能存储六个元素,这不适合今天的安全要求。要增加其大小,您可以使用 copyOf() 创建一个新的、较大的数组,如下所示:

password = Arrays.copyOf(password, 10);

在上述示例中,您重新分配了 password 的值为一个新数组。这个新数组是通过使用 Arrays.copyOf() 方法复制旧的 password 数组而得到的,新数组的长度为10个元素。要进行复制,您使用了接受两个参数的方法 Arrays.copyOf()。第一个参数是要复制的数组,第二个参数是您要创建的新数组的长度。

在 jshell 中运行上述代码时,您将获得类似于以下输出:

Outputpassword ==> char[10] { 'c', 'e', 'e', 'r', 's', 't', '\000', '\000', '\000', '\000' }

前一行显示密码数组现在有10个元素。前六个元素来自原始password数组,经过字母排序后变为'c', 'e', 'e', 'r', 's', 't'。最后四个值为空,因为Arrays.copyOf()在增加元素数量时会用空值填充新元素。

您还可以通过检查每个数组对象都具有的length属性来验证新数组有10个元素。您可以以通常的方式打印这个值:

System.out.println(password.length);

在这里,您使用println()方法并将password.length作为参数传递。从jshell的输出将是:

Output10

本节介绍的方法是与数组相关的一些最有用的方法。您可以根据官方数组文档进一步探索Arrays类中的各种方法。

结论

在本教程中,您使用Java数组来组合相关项目。您学习了如何创建数组,如何查看它们以及如何使用其内容。您还学习了处理数组的最佳实践和有用方法。

有关Java的更多信息,请查看我们的如何在Java中编码系列。

相关推荐

上海到北京开车要走多久?路线该如何选择?
365bet体育投注在线

上海到北京开车要走多久?路线该如何选择?

📅 08-29 👁️ 361
如何建立一个群自己当群主
中爱365APP

如何建立一个群自己当群主

📅 09-29 👁️ 9974
快递爆仓是什么意思?快递爆仓的物流原因、演变与对策
365bet体育投注在线

快递爆仓是什么意思?快递爆仓的物流原因、演变与对策

📅 07-09 👁️ 3592