在不更改堆栈的情况下更改添加到堆栈的变量的值?
Change value of variable added to stack without changing stack?
我有一堆数组。我还有一个数组,我将其压入堆栈、修改并再次压入。每当我更改数组的值时,堆栈中的所有变量都会以相同的方式修改。例如:
int[] array = {1, 1};
Stack<int[]> stack = new Stack<int[]>();
stack.push(array);
array = {1, 3};
stack.push(array);
堆栈应该是 {{1, 1}, {1, 3}}
,但实际上是 {{1, 3}, {1, 3}}
。我试过 stack.push({1, 3});
但这会导致错误。我也不能每次都声明一个新数组,因为整个事情都是循环发生的。
您的代码无法编译。不编译解释的部分先忽略不计java.
I also can't declare a new array every time because this whole thing is happening in a loop.
诺诺。你可以。 int[]
是对象类型(与原始类型相反)。这意味着该变量实际上代表一张藏宝图,而不是宝藏。那么,让我们分解一下:
int[] array = {1, 1};
这只是语法糖:
int[] array = new int[] {1, 1};
这只是语法糖:
int[] array = new int[2];
array[0] = 1;
array[1] = 1;
此外,new int[2]
命令创建新宝藏并将其埋在沙子中,int[] array
部分制作新的藏宝图,中间的=
涂鸦一个不错的X-marks-the-spot 在你的地图上。 []
和 .
是 java-ese 的意思是:走到 X 并向下挖掘。 =
是 java-ese 的意思是:拿一块橡皮擦掉那个 X,然后把它放在别的地方。
此外,在 java 中,每当您将内容传递给方法时,它总是副本(但是,map 的副本,而不是 宝物).
这种思考方式正是 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,new
创造新宝藏。我们这里要2个宝物:一个是{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 需要知道你要创建的数组的类型。写int x = { ... }
的时候就很明显了。当你写 x = { ... }
时,它稍微不太明显,这大概是 为什么 规范不允许 shorthand。请注意,写 int[] x = new int[] {1, 3};
也完全没问题; int x[] = {1, 3};
只是方便 shorthand.
// 这需要你的数组映射,跟随 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());
您的堆栈现在将保存正确的值
stack [0] --> {1,1}
[1] --> {1,3}
或者,每次您都可以将一个新数组分配给 array
,例如
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]
我有一堆数组。我还有一个数组,我将其压入堆栈、修改并再次压入。每当我更改数组的值时,堆栈中的所有变量都会以相同的方式修改。例如:
int[] array = {1, 1};
Stack<int[]> stack = new Stack<int[]>();
stack.push(array);
array = {1, 3};
stack.push(array);
堆栈应该是 {{1, 1}, {1, 3}}
,但实际上是 {{1, 3}, {1, 3}}
。我试过 stack.push({1, 3});
但这会导致错误。我也不能每次都声明一个新数组,因为整个事情都是循环发生的。
您的代码无法编译。不编译解释的部分先忽略不计java.
I also can't declare a new array every time because this whole thing is happening in a loop.
诺诺。你可以。 int[]
是对象类型(与原始类型相反)。这意味着该变量实际上代表一张藏宝图,而不是宝藏。那么,让我们分解一下:
int[] array = {1, 1};
这只是语法糖:
int[] array = new int[] {1, 1};
这只是语法糖:
int[] array = new int[2];
array[0] = 1;
array[1] = 1;
此外,new int[2]
命令创建新宝藏并将其埋在沙子中,int[] array
部分制作新的藏宝图,中间的=
涂鸦一个不错的X-marks-the-spot 在你的地图上。 []
和 .
是 java-ese 的意思是:走到 X 并向下挖掘。 =
是 java-ese 的意思是:拿一块橡皮擦掉那个 X,然后把它放在别的地方。
此外,在 java 中,每当您将内容传递给方法时,它总是副本(但是,map 的副本,而不是 宝物).
这种思考方式正是 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,new
创造新宝藏。我们这里要2个宝物:一个是{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 需要知道你要创建的数组的类型。写int x = { ... }
的时候就很明显了。当你写 x = { ... }
时,它稍微不太明显,这大概是 为什么 规范不允许 shorthand。请注意,写 int[] x = new int[] {1, 3};
也完全没问题; int x[] = {1, 3};
只是方便 shorthand.
// 这需要你的数组映射,跟随 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());
您的堆栈现在将保存正确的值
stack [0] --> {1,1}
[1] --> {1,3}
或者,每次您都可以将一个新数组分配给 array
,例如
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]