如何保存在函数内部所做的数组更改?
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 使用泛型,我们不需要显式转换。
我需要制作一个 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 使用泛型,我们不需要显式转换。