【问题标题】:I need to make a copy of an array of cards, but I am only given the address of the array I need to copy我需要复制一组卡片,但我只得到了我需要复制的数组的地址
【发布时间】:2012-10-09 14:07:24
【问题描述】:

我需要制作一个我无法直接访问的卡片数组的临时副本,因为它位于另一个名为 Hand 的类中。我得到了一个名为 getHand() 的方法,它返回对我需要在作为 Hand 的子类 RummyHand 类中的副本的数组的引用。变量 rummyHand 是 RummyHand 类中的一个实例变量,是一个 Hand 对象。如果这很重要,我也在日食中工作。

但这都不是:

卡[] temp = 新卡[8];

temp = rummyHand.getHand();

或者这个:

卡[] temp = rummyHand.getHand();

按照我的预期复制了数组。

【问题讨论】:

    标签: java arrays eclipse


    【解决方案1】:

    您可以使用Arrays.copyOfSystem.arrayCopy 来复制一个数组,或者更简单的clone():

    Card[] temp = rummyHand.getHand().clone();
    

    请注意,使用 = 运算符永远不会复制任何数据。 = 所做的只是让变量引用不同的东西。理解这一点很重要,否则会给您带来很多麻烦。

    在(希望有用的)细节中:

    new Card[8];
    

    创建一个数组:一个新的内存区域,大到足以容纳指向 8 张卡片的指针。

    Card[] temp
    

    创建一个必须指向某种卡片数组的变量。

    =
    

    在中间使变量指向该内存区域。表达式

    rummyHand.getHand();
    

    为您提供不同内存区域的地址。所以这条线

    temp = rummyHand.getHand();
    

    只是让temp 变量指向该内存区域。 copyOfarrayCopyclone 都通过创建一个新数组并用原始数组中的引用填充它,然后将新数组交还给您来工作。

    【讨论】:

    • 有更简单的方法 - 例如克隆或 java.util.Arrays。
    • @gustafc 你说的很对。我已经相应地更新了答案。
    【解决方案2】:

    使用

    Card[] hand = rummyHand.getHand();
    Card[] temp = new Card[hand.length()];
    System.arraycopy(hand,0,temp,0,hand.length());
    

    之后你有一个数组的副本 - 但请记住,对数组中卡片的引用仍然是相同的。因此,如果您更改 temp 中卡片的属性,它也会更改 hand 中的卡片,因为两个数组都包含相同的“卡片实例”。

    【讨论】:

      【解决方案3】:

      你可以使用clone复制一个数组:

      Card[] temp = rummyHand.getHand().clone();
      

      这将为您提供与原件长度相同的精确副本。如果你想要复制的八个元素不考虑原件的长度,你可以使用Arrays.copyOf

      Card[] temp = Arrays.copyOf(rummyHand.getHand(), 8);
      

      【讨论】:

        【解决方案4】:

        有几种方法可以复制数组。最基本的是创建一个与源数组大小相同的数组,然后遍历源数组的元素并将每个元素添加到新副本中:

        Card[] source = rummyHand.getHand();
        Card[] temp = new Card[source.length];
        
        // for loop:
        for (int i = 0; i < source.length; i++)
            temp[i] = source[i];
        

        但是有一些 java 实用程序类可以为你做这件事。见Arrays.copyOf

        Card[] temp = Arrays.copyOf(source, source.length);
        

        但请注意,您的新数组将包含与源数组相同的 Card 引用,这意味着对数组中对象的任何更改不会更改副本:它们会更改实际对象。如果您需要数组的 contents 副本,那么您需要使用循环,并在将每个 Card 添加到 temp 数组之前对其进行复制。

        当您这样做时:temp = rummyHand.getHand();,您将获得对原始数组的引用,不是副本,因此您所做的任何更改都会更改 @987654329 中的数组@对象..

        【讨论】:

        • 为什么不使用 System.arraycopy()?它要快得多。
        • @Robert 比什么更快?请注意,我提到了Arrays.copyOf。出于说明目的,我包含了 for 循环。
        猜你喜欢
        • 2019-06-30
        • 1970-01-01
        • 2018-07-13
        • 2020-05-22
        • 2012-05-22
        • 1970-01-01
        • 2014-11-26
        • 2016-06-29
        • 1970-01-01
        相关资源
        最近更新 更多