我在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 for Visual Studio(C#)中存在类似的功能。
仅供参考:我正在使用Eclipse Luna SR 2(4.4.2)
答案 0 :(得分:10)
鼠标悬停for
语句,右键单击,快速修复( Ctrl + 1 ),转换为索引循环。
应该工作!
答案 1 :(得分:7)
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);
}
答案 2 :(得分:6)
在我的eclipse(Kepler RC2)中,它可以选择for
关键字并使用上下文菜单中的快速修复或点击 CTRL + 1 为快捷方式。然后Eclipse为我提供了转换为索引&#39;用于&#39;环路&#34;或者&#34;转换为基于Iterator的&#39;用于&#39;环路&#34;
答案 3 :(得分:1)
您可以使用:
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);
}
但我喜欢使用的第一个。
答案 4 :(得分:0)
小心这种重构。
原因是对于传统的链表,您的第二个for
循环公式为O(N * N),因为您必须遍历链表才能评估names.get(i);
。这可能会变得昂贵。
从for(String name:names) {
移动时,请考虑性能影响。可能有更好的方法来修复你的直接错误,并保留当前的&#34; Big O&#34;。
for(String name : names.subList(1, names.size() - 1)) {
就是这样一种方式(Acknowledge @JB Nizet)。
答案 5 :(得分:0)
不要进行索引迭代!
这对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);
}
答案 6 :(得分:-2)
使用java 8时,您可以使用stream api
names.stream().skip(1).reverse().skip(1).reverse().foreach(
name -> do something(name)
);
像这样......