【问题标题】:Foreach can not manipulate a String list?Foreach 不能操作一个String列表?
【发布时间】:2016-07-04 18:46:51
【问题描述】:

我在该主题上找到了this 线程,我想知道为什么在 Java 中替换 List 中的值如此困难。

我的代码看起来很丑:

    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的“按值复制”问题,String是不可变的,但为什么要这样实现呢?为什么command 是原始引用的副本而不是原始引用本身?

【问题讨论】:

  • 不变性不是这里的问题。 command 是一个变量,它引用了列表的第 n 个元素,但是给这个变量分配一个不同的值只会导致它引用其他东西,对列表没有任何影响。

标签: java list immutability pass-by-value


【解决方案1】:

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

for-each 循环隐藏了迭代器,因此您不能调用remove。因此,for-each 循环不可用于过滤。 同样,它不适用于需要在遍历列表或数组时替换元素的循环。 最后,它不适用于必须遍历多个循环的循环并行收集。设计师们知道这些缺点,他们有意识地决定采用一个干净、简单的结构,可以覆盖绝大多数情况。

您可以使用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++;
}

【讨论】:

  • 如果你调用“remove”会有什么问题?
  • @TrudleR 没有可见 iterator 可以调用remove(带有for-each 循环)。
【解决方案2】:

从 Java-8 开始,您可以使用 List.replaceAll 的新选项:

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

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

【讨论】:

  • 这是我的问题的解决方案,谢谢。但艾略特的回答更适合这个问题。非常感谢您的意见! :)
【解决方案3】:

会是这样的:

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

【讨论】:

    猜你喜欢
    • 2015-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-08
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多