在Java中,可以在遍历列表时修改它吗?

在Java中,可以在遍历列表时修改它吗?,java,arraylist,Java,Arraylist,我知道在Java中,在迭代过程中不应该修改集合,例如删除或添加元素。但是,如何更改列表中的元素呢?例如,如果我们有 List<String> letters = new ArrayList<String>(); letters.add("A"); letters.add("B"); letters.add("C"); int i = 0; for (String letter : letters) { letters.set(i, "D"); i++;

我知道在Java中,在迭代过程中不应该修改
集合,例如删除或添加元素。但是,如何更改列表中的元素呢?例如,如果我们有

List<String> letters = new ArrayList<String>();
letters.add("A");
letters.add("B");
letters.add("C");
int i = 0;

for (String letter : letters) {
    letters.set(i, "D");
    i++;
}
List letters=new ArrayList();
信函。添加(“A”);
字母。添加(“B”);
字母。添加(“C”);
int i=0;
for(字符串字母:字母){
字母集(i,“D”);
i++;
}

所以,我不是说修改存储在元素中的对象;我说的是改变物体是什么。列表的大小没有改变,但索引处的对象正在改变,因此从技术上讲,列表正在被修改。我的老板声称这个代码很好(而且看起来确实有效),但我仍然不认为它是正确的。如果使用ListIterator的set(E)方法,使用不同的方法会更好吗

在遍历列表时修改列表中的元素的想法没有什么错(不要修改列表本身,这是不推荐的),但是可以这样更好地表达:

for (int i = 0; i < letters.size(); i++) {
    letters.set(i, "D");
}
for(int i=0;i
在最后,整个列表将以字母
“D”
作为其内容。使用增强的
for
循环不是一个好主意在这种情况下,您没有使用迭代变量进行任何操作,而且您不能使用迭代变量修改列表的内容

请注意,上面的代码片段并没有修改列表的结构,这意味着:没有添加或删除元素,列表的大小保持不变。简单地用另一个元素替换一个元素并不算是结构修改。以下是@ZouZou在评论中引用的文档的最新版本,其中指出:

结构修改是添加或删除一个或多个元素,或显式调整支持数组大小的任何操作;仅设置元素的值不是结构修改

使用
如果要删除它,请执行以下操作:

for (Iterator<String> it = userList.iterator(); it.hasNext() ;)
{
    if (wordsToRemove.contains(word))
    {
        it.remove();
    }
}
for(Iterator it=userList.Iterator();it.hasNext();)
{
if(wordsToRemove.contains(word))
{
it.remove();
}
}
Java8的
stream()
接口提供了一种很好的方法来更新列表

要安全地更新列表中的项目,请使用
map()

List letters=new ArrayList();
//向列表中添加内容
letters=letters.stream().map(x->“D”).collect(Collectors.toList());
要安全地将项目移除到位,请使用
filter()


letters.stream().filter(x->!x.equals(“A”)).collect(collector.toList());
使用Java 8

为了安全撤离

letters.removeIf(x -> !x.equals("A"));

如果不打算使用变量字母,为什么要使用foreach
?为什么不试试看它是否有效?在问这个问题之前你试过吗?这在文档中有说明:“结构修改是指添加或删除一个或多个元素,或显式调整支持数组大小的任何操作;仅设置元素的值不是结构修改。”谢谢邹祖。我发现,“请注意,Iterator.remove是在迭代过程中修改集合的唯一安全方法;如果在迭代过程中以任何其他方式修改了基础集合,则该行为是未指定的。”但您的语句正是我要查找的语句。我在javadoc中查找列表,但它不在那里。我在ArrayList中看到了它。谢谢。+1如果您使用CopyOnWriteArrayList,您可以在迭代时修改它。我知道我没有使用迭代变量。这是一个基于使用迭代变量的不同代码的简单示例。我只是想指出列表在迭代过程中发生了变化。我很难找到“结构修改”的文档,这正是我要找的!谢谢你和邹祖的回答。另外,如果你向后迭代,你可以在迭代时删除元素。这个答案是从列表中删除不是问题答案的项目。问题是如何在迭代时替换/更新/交换列表中的项。CopyOnWriteArrayList返回不支持remove()方法的迭代器。请参见在描述中就地写入两次不会使这些行对列表进行就地修改
Collectors.toList()
为您创建一个全新的列表,然后在第一个示例中以
字母
的形式存储该列表,在第二个示例中只需将其丢弃即可。