Foreach 不能操作一个String 列表?

Foreach can not manipulate a String list?

我发现 this 个关于该主题的帖子,我想知道为什么在 Java 中替换列表中的值如此困难。

我的代码看起来很丑:

    List<String> stringList = new ArrayList<>();
    // ... add some elements
    for (int i = 0; i< stringList.size(); ++i) {
        if (stringList.get(i).contains("%")) {
            stringList.set(i, stringList.get(i).replace("%", backupStorePath));
        }
    }

这真的是唯一的方法吗?为什么我不能使用 foreach 循环?

for (String command : stringList) {
    command = command.replace("%", backupStorePath);
}

这一定是java的"Copy by value"问题,String是不可变的,但为什么要这样实现呢?为什么 command 是原始参考的副本而不是原始文件本身?

来自Java Programming Language: The For-Each Loop强调添加)

The for-each loop hides the iterator, so you cannot call remove. Therefore, the for-each loop is not usable for filtering. Similarly it is not usable for loops where you need to replace elements in a list or array as you traverse it. Finally, it is not usable for loops that must iterate over multiple collections in parallel. These shortcomings were known by the designers, who made a conscious decision to go with a clean, simple construct that would cover the great majority of cases.

您可以使用 Iteratorindex。像

// ... add some elements
Iterator<String> stringIter = stringList.iterator();
int i = 0;
while (stringIter.hasNext()) {
    String command = stringIter.next();
    if (command.contains("%")) {
        command = command.replace("%", backupStorePath);
        stringList.set(i, command);
    }
    i++;
}

因为 Java-8 你有一个新的选项可以使用 List.replaceAll:

stringList.replaceAll(command -> command.replace("%", backupStorePath));

请注意 for 循环适用于任何 Iterable,而不仅仅是 List。并且大多数其他可迭代对象不支持元素替换。因此,即使 Java 设计人员决定支持修改,也有必要将 List 和非 List 情况分开,这肯定会增加一些复杂性。

它会像这样:

List list1 = new ArrayList();
List list 2 = list1;
list2 = new LinkedList();  //this just make list2 to point to an new Object no reference about list1.

所以你的代码:

command = command.replace("%", backupStorePath);  //this just make command to a new point of memory not have any chang about your list