[英]Inconsistent behavior on java's for-each
考虑以下代码:
class Jm44 {
public static void main(String args[]){
int []arr = {1,2,3,4};
for ( int i : arr )
{
arr[i] = 0;
}
for ( int i : arr )
{
System.out.println(i);
}
}
}
它打印:
0
0
3
0
这是什么? For-each应该在数组中的所有元素上运行,为什么要运行arr[3]=0
但不运行arr[2]=0
呢?
如果您看一下第一个循环中的arr
发生了什么,这将变得显而易见。
int[] arr = {1, 2, 3, 4};
for (int i : arr) {
System.out.println("i = " + i);
arr[i] = 0;
System.out.println("arr = " + Arrays.toString(arr));
}
for (int i : arr) {
System.out.println(i);
}
打印:
i = 1 arr = [1, 0, 3, 4] i = 0 arr = [0, 0, 3, 4] i = 3 arr = [0, 0, 3, 0] i = 0 arr = [0, 0, 3, 0] 0 0 3 0
您正在使用数组中的值作为索引来修改数组中的值。 “ foreach”循环遍历数组的值 ,而不遍历数组的索引 。 删除语法糖后,这是您的foreach循环实际上是:
int[] arr = {1, 2, 3, 4};
for (int index = 0; index < arr.length; index++) {
int i = arr[index];
arr[i] = 0;
}
for (int i : arr) {
System.out.println(i);
}
为了能够对数组建立索引,您需要使用传统的for循环,如下所示:
int[] arr = {1, 2, 3, 4};
for (int i = 0; i < arr.length; i++) {
arr[i] = 0;
}
for (int i : arr) {
System.out.println(i);
}
int []arr = {1,2,3,4};
for ( int i : arr )
{
arr[i] = 0;
}
在调试器中观看arr。
1,2,3,4 (initially)
1,0,3,4 (after we change arr[arr[0]], or arr[1])
0,0,3,4 (after we change arr[arr[1]], or arr[0])
0,0,3,0 (after we change arr[arr[2]], or arr[3])
0,0,3,0 (after we change arr[arr[3]], or arr[0] (no change, actually)
在Java中,使用
for (int i : arr)
语法遍历数组中的值 ,而不是索引 。 这与JavaScript循环不同
for (var i in arr)
遍历索引。 数组也从0开始索引-数组的第一项是arr[0]
。 @Esko的答案显示了实际情况。
因为
for ( int i : arr )
{
arr[i] = 0;
}
不会将数组设置为0s。
当然,你的意思是说
for(int i = 0; i < arr.length(); i++){
arr[i] = 0;
}
您不能使用foreach循环在数组中设置值。 for每个循环的工作方式与您预期的略有不同。
(说明即将到来)
您必须注意不要混淆数组元素的索引和值
这些是第一个循环的每次迭代前后的数组值,包括i的值:
{1,2,3,4}
{1,0,3,4} i = 1
{0,0,3,4} i = 0
{0,0,3,0} i = 3
{0,0,3,0} i = 0
不要混淆循环计数器和数组值...我认为这是在这里发生的
展开第一个循环:
int[] arr = { 1, 2, 3, 4 };
int i;
i = arr[0]; // i = 1
arr[i] = 0; // arr[1] = 0
i = arr[1]; // i = 0
arr[i] = 0; // arr[0] = 0
i = arr[2]; // i = 3
arr[i] = 0; // arr[3] = 0
i = arr[3]; // i = 0
arr[i] = 0; // arr[0] = 0
因此, arr[2]
(第三个元素)永远不会设置为零; 它保留其原始值3。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.