将 foreach 重构为 for 循环

Refactor foreach to for loop

我在 Java 中有一个 foreach 循环(这里是简化版)

List<String> names = getNames();
for(String name:names) {
    doSomething(name);
}

是否有自动重构为传统 for 循环的方法?

我知道如何手动操作

List<String> names = getNames();
for(int i=0; i<names.size(); i++) {
    String name = names.get(i);
    doSomething(name);
}

如您所见,for 语句本身需要进行一些输入,还需要再次引入变量 name 并为其赋值 names.get(i)。总的来说,手动编辑对我来说太容易出错了。

我为什么要这样做?我必须修复一个错误,修复方法是从索引 1 而不是索引 0 开始,并在索引 n-1 而不是结束处结束(不幸的是我无法立即修复输入,我需要等待库更新如果这被认为是错误)。

我尝试了什么?我右键单击 for 关键字并单击 "Refactor",但据我从上下文菜单条目中获得的信息,其中的任何内容都无法为我完成工作。

为什么我认为这在理论上可行?因为 Resharper 中存在类似的功能 Visual Studio (C#).

仅供参考:我正在使用 Eclipse Luna SR 2 (4.4.2)

小心重构。

原因是对于传统的链表,您的第二个 for 循环公式是 O(N * N) 因为您必须遍历链表才能评估 names.get(i); .那可能会变得昂贵。

for(String name:names) { 迁移时请务必考虑性能影响。可能有更好的方法来修复您的直接错误,并保留当前的 ​​"Big O".

for(String name : names.subList(1, names.size() - 1)) {

就是这样一种方式(确认@JB Nizet)。

在我的 eclipse (Kepler RC2) 中,它适用于 select for 关键字并使用上下文菜单中的快速修复或点击 CTRL +1 为快捷方式。然后 Eclipse 为我提供 "Convert to indexed 'for' loop" 或 "Convert to Iterator-based 'for' loop".

鼠标悬停在for语句上,右击,Quick fix (Ctrl+1),转换为索引循环.

应该可以!

List<String> names = getNames();
names = names.subList(1, names.size() - 1);
for(String name : names) {
    doSomething(name);
}

当然,如果需要多次执行,可以将其放入可重用的方法中:

public static List<String> fixList(List<String> names) {
    return names.subList(1, names.size() - 1);
}

然后用作

List<String> names = fixList(getNames());
for(String name : names) {
    doSomething(name);
}

当使用 java 8 时,您可以使用流 api

names.stream().skip(1).reverse().skip(1).reverse().foreach(
    name -> do something(name)
);

像这样...

您可以使用:

names = names.subList(1, names.size()-1);
for (String name : names) {
   doSomething(name);
}

或手动输入:

for (int i = 1; i < names.size()-1; i++) {
   String name = names.get(i);
    doSomething(name);
}

但我更喜欢使用第一个。

不要进行索引迭代! 这在 List.

的所有实现中表现不佳

如果此代码很热,最好选择 Iterator 并让 JIT 优化 Iterator

所以要么这样写:

List<String> names = getNames();
for (String name : names.subList(1, names.size() - 1)) {
    doSomething(name);
}

或者那个(少一个分配):

Iterator<String> it = getNames().iterator();
it.next(); // You seem to be sure there is more than one element in the list
while (it.hasNext()) {
    String name = it.next();
    doSomething(name);
}

就我而言,我需要将 foreach 转换为使用索引。 这是我的两分钱

Integer index=0;
                  
      for (final String OneCell :CellList){
     // Your code use the index
             index=index+1;
     }