Java 在不更改堆栈的情况下更改添加到堆栈的变量的值?
我有一堆数组。我还有一个数组,我将它推入堆栈,修改,然后再次推入。每当我更改数组的值时,堆栈中的所有变量都以相同的方式修改。例如:Java 在不更改堆栈的情况下更改添加到堆栈的变量的值?,java,arrays,stack,Java,Arrays,Stack,我有一堆数组。我还有一个数组,我将它推入堆栈,修改,然后再次推入。每当我更改数组的值时,堆栈中的所有变量都以相同的方式修改。例如: int[] array = {1, 1}; Stack<int[]> stack = new Stack<int[]>(); stack.push(array); array = {1, 3}; stack.push(array); int[]数组={1,1}; 堆栈=新堆栈(); 堆栈推送(数组); 数组={1,3}; 堆栈推送(数组);
int[] array = {1, 1};
Stack<int[]> stack = new Stack<int[]>();
stack.push(array);
array = {1, 3};
stack.push(array);
int[]数组={1,1};
堆栈=新堆栈();
堆栈推送(数组);
数组={1,3};
堆栈推送(数组);
堆栈应该是
{1,1},{1,3}
,但它是{1,3},{1,3}
。我尝试了stack.push({1,3})代码>但这会导致错误。我也不能每次都声明一个新数组,因为整个过程都发生在一个循环中。您的代码无法编译。让我们忽略不编译和解释java的部分
我也不能每次都声明一个新数组,因为整个过程都是在一个循环中发生的
不。你可以int[]
是一种对象类型(与基元类型相反)。这意味着这个变量实际上代表了一张藏宝图,而不是宝藏。那么,让我们把它分解一下:
int[]数组={1,1}代码>
这只是语法:
int[] array = new int[2];
array[0] = 1;
array[1] = 1;
int[]数组=新的int[]{1,1}代码>
这只是语法糖:
int[] array = new int[2];
array[0] = 1;
array[1] = 1;
此外,<代码> new int(2)< /C>命令创建新的财宝并将其埋入沙中,并且<代码> int []数组< /代码>部分生成一个新的宝库图,中间的<代码>=<代码>在您的地图上刻画出一个漂亮的X-MARK-SPOT。代码>[]
和
是java ese的目标:走到X并向下挖掘<代码>=
是java ese的意思:用橡皮擦擦去X,然后把它放在其他地方
而且,在java中,每当您将内容传递给方法时,它总是副本(但是,地图的副本,而不是宝藏的副本)
这种思考方式正是java内存模型的工作方式,永远不会让您出错。因此:
int[] array = {1, 1};
// 1 treasure chest made.
// 1 treasure map made. The map is called `array`.
// X marked on the map.
stack.push(array);
// Take your `stack` map, walk to the X. Dig down.
// Open the chest you find here, and yell into it: "push".
// Make a copy of your `array` map, and hand it over.
array = {1, 3};
// This isn't legal java.
array[1] = 3;
// This takes your array map, follows the X,
// digs, tosses out the second element you find
// in the box, and then puts a 3 in there instead.
当然,堆栈看到的是相同的3:只有一个宝藏,而且你们都有一张到它的地图
让我们把它修好。记住,=
清除X,而新建
生成新的宝藏。我们想要两件珍宝:一件是{1,1}
,另一件是{1,3}
。因此,new
涉及其中,=
也很有用。让我们使用它们:
int[] array = {1, 1};
stack.push(array);
array = new int[] {1, 3};
// The above is the syntax for making a new int array.
stack.push(array);
System.out.println(stack);
成功!现在它起作用了
原因int[]x={1,3}
是合法的,但是x={1,1}代码>不是,是语言的一个怪癖。它在语言规范中int[]x=…
使用初始值设定项声明新变量,而x=…
是赋值表达式
Java需要知道要生成的数组的类型。在编写intx={…}
时,这一点非常明显。当您编写x={…}
时,它就不那么明显了,这大概就是规范不允许速记的原因。请注意,编写int[]x=newint[]{1,3}是非常好的代码>以及<代码>整数x[]={1,3}代码>仅仅是方便的速记
//这将获取你的数组映射,跟随X,
//挖掘,扔掉你找到的第二个元素
//在框中,然后在其中放一个3。我想你的sintax只是循环中代码的简化
由于您的需求是使用相同的阵列实例,而不需要创建更多的阵列,您需要的是在每次迭代时推送此阵列的浅拷贝。基本体的浅克隆不会受到对同一对象的进一步修改的影响,因此正确的值将被复制,而不会被您在以下迭代中进行的更新所更改
仅此而已:
int[] array = {1, 1};
Stack<int[]> stack = new Stack<int[]>();
stack.push(array.clone());
//array = {1,3}; ---> in order to mimic this, I manually alter array's values
array[0]=1;
array[1]=3;
stack.push(array.clone());
或者,每次您都可以将新数组分配给数组
,例如
import java.util.Arrays;
import java.util.Stack;
public class Main {
public static void main(String args[]) {
int[] array = { 1, 1 };
Stack<int[]> stack = new Stack<int[]>();
stack.push(array);
array = new int[] { 1, 3 };
stack.push(array);
stack.forEach(e -> System.out.println(Arrays.toString(e)));
}
}
[1, 1]
[1, 3]