public class Test {
public static void main(String[] args) {
int[] oldList = {1, 2, 3, 4, 5};
reverse(oldList);
for (int i = 0; i < oldList.length; i++)
System.out.print(oldList[i] + " ");
}
public static void reverse(int[] list) {
int[] newList = new int[list.length];
for (int i = 0; i < list.length; i++)
newList[i] = list[list.length - 1 - i];
list = newList;
}
}
为什么该方法不适用仍然得到1 2 3 4 5? 谢谢!
答案 0 :(得分:3)
这种情况正在发生,因为Java是按值传递的。这意味着当您将参数传递给方法时,您将对它进行传递,不是参数本身。您在方法中所做的更改已得到解决,但在这种情况下,您不会返回已修改的参数。试试这个简单的实验来看看我的意思:
public static void main(String[] args) {
int x = 0;
foo(x);
System.out.println(x);
}
public static void foo(int x) {
x = 4;
}
此程序将打印0
,因为更改基本上已被丢弃。要返回复制的引用,请尝试:
public static int[] reverse(int[] list) {
int[] newList = new int[list.length];
for (int i = 0; i < list.length; i++) {
newList[i] = list[list.length - 1 - i];
}
return newList;
}
在你的主要:
oldList = reverse(oldList);
更深入的答案:
答案 1 :(得分:1)
有几个问题。您可以使用以下两个选项修复它:
选项1:
1)制作原始数组的新副本并将其用作参考数组以反转
2)在反向函数中,更新已在参数中传递的数组的值,并使用引用数组
将其反转public class Test {
public static void main(String[] args) {
int[] oldList = {1, 2, 3, 4, 5};
reverse(oldList);
for (int i = 0; i < oldList.length; i++)
System.out.print(oldList[i] + " ");
}
public static void reverse(int[] list) {
// create a copy of initial array to use it to reverse
int[] newList = Arrays.copyOf(list,list.length);
for (int i = 0; i < list.length; i++)
// update original array and reverse it. Calling method still have reference to this array
list[i] = newList[list.length - 1 - i];
}
}
控制台输出:
PS:这里的想法是确保数组的引用保持不变。您可以使用另一个数组作为引用数组或使用另一个局部变量并在数组内交换两个值或在i和n-i-1变量之间执行XOR。上面分享了1种方法,有多种方式。
选项2:
1)无需以反向方法
将旧数组的引用复制到新数组2)将新数组引用返回给调用方法
3)对于上述点,您还必须更改反向功能的返回类型
4)将新的数组引用保存在main方法的变量中,然后从中进行打印。
请在下面找到我的评论:
public class Test {
public static void main(String[] args) {
int[] oldList = {1, 2, 3, 4, 5};
//save the return list to a variable
int[] newList= reverse(oldList);
for (int i = 0; i < newList.length; i++)
//print the data from new list
System.out.print(newList[i] + " ");
}
// change the return type
public static int[] reverse(int[] list) {
int[] newList = new int[list.length];
for (int i = 0; i < list.length; i++)
newList[i] = list[list.length - 1 - i];
//remove this line as there is no point of copying old array back to new array
// list = newList;
//retrun newlist reference to the calling method
return newList;
}
}
控制台输出:
答案 2 :(得分:0)
Java is always pass-by-value。这对于对象和数组引用意味着什么?在Java中,我们只通过引用处理对象。引用存在于堆栈中,实际对象存在于堆上。引用存储实际对象所在的地址。
如果将对象传递给方法,则将引用值(即对象所在的地址)作为参数传递。对于某些方法foo(Object o)
,这意味着:如果您在o
的正文中重新分配foo
(例如通过o = new Object();
,则此更改将不会在list
之外显示方法
要解决您的问题,您可能必须就地进行反转(即直接在public static void reverse(final int[] values) {
final int length = values.length;
for (int i = 0; i < length / 2; ++i) {
final int j = length - i - 1;
swap(values, i, j);
}
}
public static void swap(final int[] values, final int i, final int j) {
int tmp = values[i];
values[i] = values[j];
values[j] = tmp;
}
上)或返回新创建的数组。以下是就地变体的实现:
return
对于list
- 变体的实现,请查看其他答案之一,因为其他每个答案似乎都在此实现变体。
对您的代码的一些评论:
为数组参数指定名称list
令人困惑。 if
与数组不同,是具有不同属性的不同数据结构。
你不应该忽略围绕一行else
- ,for
- ,__main__.py
- ,......身体的可选括号。这可能是令人讨厌的错误的根源,并被视为不良做法。
你应该多关心一下。你的缩进。请记住,您的源代码是一种通讯方式。通过简单的规则(如缩进)可以传输的语义越多,理解源代码就越容易。
答案 3 :(得分:0)
这种情况正在发生,因为您正在更改新区域,并且语句list = newList;
不会影响原始列表,因为java是按值传递的,而您只是在反向函数中覆盖指针。
相反,您应该返回新数组并覆盖旧数组,如:
public class HelloWorld
{
public static void main(String[] args) {
int[] oldList = {1, 2, 3, 4, 5};
oldList = reverse(oldList);
for (int i = 0; i < oldList.length; i++)
System.out.print(oldList[i] + " ");
}
public static int[] reverse(int[] list) {
int[] newList = new int[list.length];
for (int i = 0; i < list.length; i++)
newList[i] = list[list.length - 1 - i];
return newList;
}
}