我在主题上找到了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
是原始引用的副本而不是原始引用?
答案 0 :(得分:5)
从Java-8开始,您有了一个使用List.replaceAll
的新选项:
stringList.replaceAll(command -> command.replace("%", backupStorePath));
请注意,for
循环适用于任何Iterable
,而不仅仅适用于List
。并且大多数其他迭代不支持元素替换。因此,即使Java设计者决定支持修改,也有必要将List和非List案例分开,这肯定会增加一些复杂性。
答案 1 :(得分:3)
来自Java Programming Language: The For-Each Loop( 强调 已添加)
for-each循环隐藏了迭代器,因此您无法调用
remove
。因此,for-each循环不可用于过滤。 同样,它不适用于需要在遍历时替换列表或数组中的元素的循环。 最后,它不适用于必须遍历多个循环的循环收集并行。这些缺点是设计师所熟知的,他们有意识地决定采用干净,简单的结构来覆盖绝大多数情况。
您可以使用Iterator
和index
。像
// ... 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++;
}
答案 2 :(得分:0)
它会是这样的:
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