在forEach循环中使用乘法时,Java ArrayList.set()方法出现意外行为

noj0wjuj  于 2022-12-25  发布在  Java
关注(0)|答案(2)|浏览(114)

设置初始数组值(没有问题):

import java.util.ArrayList;
public class arraylists {

    public static void main (String[] args) {
        ArrayList<Integer> numbers = new ArrayList<Integer>();
        numbers.add(3);
        numbers.add(1);
        numbers.add(4);
        numbers.add(2);
        System.out.println(numbers.toString());
    }
}

控制台输出:[三、一、四、二]
正在尝试forEach添加(没有问题):

numbers.forEach(number -> {
    numbers.set(numbers.indexOf(number), number + 10);
});
System.out.println(numbers.toString());

控制台输出:[十三、十一、十四、十二]
正在尝试forEach乘法:

numbers.forEach(number -> {
    numbers.set(numbers.indexOf(number), number * 2);
});
System.out.println(numbers.toString());

控制台输出:[六、**四、八、]
我的问题是,为什么乘法循环后的数组在索引1处的值为4,在索引3处的值为2?它们不应该分别为1 * 2 = 2和2 * 2 = 4吗?
我尝试了上面的代码,并期望在forEach乘法之后有一个值为[6,2,8,4]的数组,但我得到的是[6,4,8,2]。

xwbd5t1u

xwbd5t1u1#

indexOf返回一个值第一次出现时的索引,让我们遍历这个循环,看看发生了什么。
1.我们从[3,1,4,2]开始
1.第一个元素是3,它的索引是0,所以我们得到[6,1,4,2]
1.第二个元素是1,它的索引是1,所以我们得到[6,2,4,2]
1.第三个元素是4,它的索引是2,所以我们得到[6,2,8,2]
1.第四个元素是2,它的第一个索引是1,所以我们得到[6,4,8,2]
这不仅是错误的(正如您所看到的),而且还意味着对于每次迭代,您需要搜索整个列表(使用indexOf),以查找您应该已经知道其位置的值。
使用一个好的旧for循环会更适合这里:

for (int i = 0; i < numbers.size(); ++i) {
    numbers.set(i, numbers.get(i) * 2);
}
mo49yndu

mo49yndu2#

在乘法过程中得到的结果不正确,因为当处理最后一个元素时,列表看起来像[6, 2, 8, 2](索引1处的元素已更改为2)。因此,indexOf()返回1,而不是3(正如您可能预期的那样)。
在这种情况下,当您需要替换列表中的每个元素时,可以使用Java 8方法List.replaceAll(),这要方便得多,因为您不需要使用索引进行拨号:

numbers.replaceAll(number -> number * 2);

System.out.println(numbers);
  • 输出:*
[6, 2, 8, 4]

相关问题