JavaRush /Java 博客 /Random-ZH /Arrays类及其用法

Arrays类及其用法

已在 Random-ZH 群组中发布
再一次问好!:) 在上一课中,我们熟悉了数组(Java数组)这样的数据结构,学习了如何创建数组、向数组填充数据,还学习了它们如何在内存中存储。今天我们将讨论一些在实际工作中经常遇到的任务和使用数组的示例。例如,想象一下这种情况:我们有一个以随机顺序写入的 10 个数字组成的数组。
//array Java, example
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
我们的任务是按升序对这个数组进行排序:从最小到最大的数字。最后它应该看起来像这样:
[-234, -2, 16, 26, 35, 43, 80, 92, 99, 167]
我们如何做到这一点?这项任务并不简单,我们以前从未这样做过:/有什么想法吗?猜猜看。例如,我们可以这样做:
  • 迭代数组的所有元素。将每个元素与下一个元素进行比较([0]with [1][1]with [2][2]with[3]等)。如果当前数组元素大于下一个元素,则交换它们并继续处理下一个元素。如果没有,请保持原样并继续。

  • 因此,在第一次遍历数组元素后,保证最大值 (167) 位于最后一个单元格中。

  • 现在,让我们再次遍历数组的所有元素,从索引为的元素开始[0],直到倒数第二个元素(最大的数字已经就位)并进行相同的比较和交换。 
    最后,在倒数第二个单元格中,我们将获得第二高值 (99)。

  • 让我们重复这项工作,次数与数组中的元素减一相同。
数组类及其用法 - 2我们有了这个想法,剩下的就是编写代码了。它看起来像这样:
public class Main {

   public static void main(String[] args) {

       int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};

       for (int i = numbers.length - 1; i > 0; i--) {
           for (int j = 0; j < i; j++) {
           /* Compare the elements in pairs,
             if they are in the wrong order,
             then swap them */
               if (numbers[j] > numbers[j + 1]) {
                   int tmp = numbers[j];
                   numbers[j] = numbers[j + 1];
                   numbers[j + 1] = tmp;
               }
           }
       }

   }
}
嗯...看起来有点复杂-_- 即使大致的操作原理很清楚,你也必须编写相当多的代码才能解决这样一个看似简单的任务。好吧,也许我们只是高估了自己?也许,到目前为止,我们所承担的任务对我们来说太艰巨了。让我们尝试做一些更简单的事情。例如,让我们采用相同的数字数组。
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
我们的任务是将其内容复制到另一个数组。
int [] numbersCopy = new int[10];
考虑一下如何利用已有的数组知识来做到这一点?例如,您可以循环遍历数组numbers并将其元素一一写入numbersCopy
public class Main {

   public static void main(String[] args) {

       int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};

       int [] numbersCopy = new int[10];

       for (int i = 0; i < numbers.length; i++) {

           numbersCopy[i] = numbers[i];
       }

   }
}
好吧,我们或多或少已经做到了!问题似乎已经解决了,但同样:如果需要经常执行,代码就会有一堆相同的循环。事实上,这些问题和其他问题早已被Java的创建者解决了,我们不需要“重新发明轮子”并为我们自己的解决方案编写一些代码。

Java 数组类

一个特殊的 Java 类将帮助您解决使用数组时的典型问题 - Arrays。此类中添加了方法来解决 Java 程序员在工作中遇到的最常见问题。例如,我们自己尝试提出解决方案的数组排序任务可以用一行解决:
public class Main {

   public static void main(String[] args) {

       int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};

       Arrays.sort(numbers);

       System.out.println(Arrays.toString(numbers));

   }
}
该方法Arrays.sort()对数组进行排序。此外,其中嵌入的算法比我们编写的代码效率更高。控制台输出:

[-234, -2, 16, 26, 35, 43, 80, 92, 99, 167]
请注意:为了将数组转换为字符串,我们使用了另一个类方法Arrays- Arrays.toString()Java 数组本身不会覆盖toString(). 所以如果你只是写
System.out.println(numbers.toString());
toString()类 方法将被调用Object。对于数组,输出将如下所示:

[I@4554617c
现在我们不详细解释为什么结论是这样的,主要是这显然不是我们需要的。但 Arrays.toString() 做到了我们想要的。顺便说一下,我们的复制问题在课堂上也很容易解决Arrays
public class Main {

   public static void main(String[] args) {

       int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};

       int [] numbersCopy = Arrays.copyOf(numbers, numbers.length);
       System.out.println(Arrays.toString(numbersCopy));

   }
}
我们向该方法Arrays.copyOf()传递原始数组(我们需要从中复制值)以及将数据复制到其中的新数组的长度。在本例中,我们表示为 长度numbers.length,因为 我们想要复制整个数组。如果我们只想复制前几个元素,我们可以为新数组指定较小的长度:
public class Main {

   public static void main(String[] args) {

       int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};

       int [] numbersCopy = Arrays.copyOf(numbers, 4);
       System.out.println(Arrays.toString(numbersCopy));

   }
}
这里我们指定新数组的长度为 4。因此,只有前 4 个元素numbers会被复制到新数组中。控制台输出:

[167, -2, 16, 99]
顺便说一句,如果您需要复制数组的一部分,但不是从头开始,而是“从中间”,Arrays您也可以这样做:
public class Main {

   public static void main(String[] args) {

       int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};

       int [] numbersCopy = Arrays.copyOfRange(numbers, 2,6);
       System.out.println(Arrays.toString(numbersCopy));

   }
}
结论:

[16, 99, 26, 92]
单元格 2(含)到 6(不含) 的数字被复制到新数组中。此外,我们可能需要比较两个数组。正如该方法一样toString(),数组本身不会重写该方法equals()。因此,如果我们尝试像这样比较它们:
public class Main {

   public static void main(String[] args) {

       int[] numbers = {1, 2, 3};
       int[] numbers2 = {1, 2, 3};

       System.out.println(numbers.equals(numbers2));
   }
}
我们得到结果了false。毕竟会调用Object.equals()比较链接的方法。当然,它们是不同的!但我们需要比较数组的内容,而不是链接。该类Arrays包含一个重写的方法equals(),它完全满足我们的需要:
public class Main {

   public static void main(String[] args) {

       int[] numbers = {1, 2, 3};
       int[] numbers2 = {1, 2, 3};

       System.out.println(Arrays.equals(numbers, numbers2));
   }
}
结论:

true
顺便说一句,该类Arrays不仅可以成功地处理普通数组,还可以处理二维数组:
public class Main {

   public static void main(String[] args) {

       int[][] numbers = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

       int[][] numbersCopy = Arrays.copyOf(numbers, numbers.length);

       System.out.println("Are these two-dimensional arrays equal to each other?");
       System.out.println(Arrays.deepEquals(numbers, numbersCopy));

       System.out.println(Arrays.deepToString(numbersCopy));
   }
}
结论:

Равны ли эти двумерные массивы между собой?
true
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
正如您所看到的,该方法Arrays.copyOf()处理复制二维数组。请注意,在这种情况下,当复制二维数组时,会发生所谓的“浅复制”。为了比较二维数组并将其输出到控制台,提供了特殊方法 -deepEqualsdeepToString();将来,您将不止一次地看到(并为此感到高兴)Java 的创建者预见到了程序员在工作时遇到的许多典型情况,并用该语言为他们实现了现成的解决方案。使用这些解决方案比重新发明轮子更容易、更方便,对吗?:) 请务必阅读OracleArrays网站上的类文档。祝你学业顺利!
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION