如何保存在函数内部所做的数组更改?

How to save array changes that were made inside function?

我需要制作一个 class 用于使用静态泛型方法处理数组。例如,在此函数中,我需要将一个数组 (arr2) 粘贴到其他数组 (arr1) 的某个索引(位置)处。

public static<T> void paste(T[] arr1, int place, T[] arr2) {
        Object[] temp = new Object[arr1.length + arr2.length];
        System.arraycopy(arr1, 0, temp, 0, place);
        System.arraycopy(arr2, 0, temp, place, arr2.length);
        System.arraycopy(arr1, place, temp, place+arr2.length, arr1.length-place);

        arr1 = (T[])temp;
    }

函数运行正常,但我看不到主函数的变化。结果始终保留在粘贴功能中。在这种情况下我能做什么?

public static void main(String[] args) {
        Integer arr[] = {1 ,2 ,3 ,4, 5};
        Integer arr2[] = {11 ,22 ,33 ,44, 55};

        paste(arr, 2, arr2);
        show(arr);

    }

您不能修改现有数组的长度。因此,paste 方法必须 return 新数组:

public static<T> T[] paste(T[] arr1, int place, T[] arr2) {
    ...

    return temp;
}

然后,在 main 方法中,将 returned 值分配给一个新变量并使用它:

T[] result = paste(arr, 2, arr2);
show(result);

当然你也可以将return值赋给已有的变量,即:

arr = paste(arr, 2, arr2);
show(arr);

为什么它不像您尝试的那样有效:

如果您在 paste 方法中重新分配 arr1,它不会影响调用方法。它只会改变方法内的局部变量(实际上是一个参数值)。无法从另一个方法中更改调用方法 (main) 中的 reference


关于泛型数组的实例化:

您可以使用反射实例化 "correct" 类型的数组(而不是 Object 类型的数组):

T[] temp = (T[]) Array.newInstance(arr1.getClass().getComponentType(), arr1.length + arr2.length);

请注意,您仍然需要强制转换,但数组的运行时类型将与 arr1 的类型相同。

当您传递 arr1 时,您传递的是数组指针 的 副本。在方法内部,您正在使用此 pointer copy ,而不是来自外部方法的 original pointer 。当您将 temp 分配给 arr1 时,您将其分配给副本而不是原件,原件仍指向另一个数组。

public static<T> T[] paste(T[] arr1, int place, T[] arr2) {
  // your code here
return temp;
}

如果您不想更改方法的签名,这是正确的做法。但是,如果我们出于某种原因假设您不想这样做。然后你需要改变作为参数传递的实际数组。在您的特定示例中,您不能这样做,因为 arr1 和 arr2 的大小都不够。但这本来是寻求更程序化的解决方案的方式。

改变其参数的过程示例:

public void mutationProcedure(int array[],int position, int changeToValue) {
    array[position] = changeToValue;
}

在这段代码中,如果我们从数组外部调用它,它的值将发生变化。

更新:无需显式转换的解决方案。我相信这是更好的解决方案。

public static<T> T[] paste(T[] arr1, int place, T[] arr2) {
        T[] temp = Arrays.copyOf(arr1, arr1.length + arr2.length);
        System.arraycopy(arr2, 0, temp, place, arr2.length);
        return temp;
}

首先,我们创建一个以 arr1 开头且大小等于两个数组的新数组。 然后我们将第二个数组从array1 end的位置复制到末尾。由于数组 class 使用泛型,我们不需要显式转换。