3 回答

TA貢獻1801條經(jīng)驗 獲得超8個贊
在這種特定情況下,使用 foreach 循環(huán),我希望您的代碼將編譯為如下所示:
Iterator<Foo> it = fooService.getFooList().iterator();
while (it.hasNext()) {
Foo foo = it.next();
// ...
}
所以在這種情況下,它沒有區(qū)別。
但是,如果您要使用不同類型的循環(huán),則可能會有所不同。例如:
for(int i = 0; i < fooService.getFooList().size(); i++){
Foo foo = fooService.getFooList().get(i);
// ...
}
如果您的列表暴露于外部修改,那么編譯器不太可能證明列表大小不會改變,因此它將調(diào)用getFooList().size()每次迭代來與 進行比較i,因此會稍微增加一些開銷。
但請注意,如果列表大小發(fā)生變化,則會i < fooService.getFooList().size()反映這一點。如果您意識到這一點,這可能很有用,但如果您不知道,則很危險。
如果您知道列表大小不會改變,那么您可以執(zhí)行以下操作來消除該開銷(或者,Iterator如果不需要索引,則只需使用或增強的 for-each 循環(huán)):
List<Foo> fooList = fooService.getFooList();
final int fooListSize = fooList.size();
for(int i = 0; i < fooListSize ; i++){
Foo foo = fooList.get(i);
// ...
}
盡管如此,與微觀優(yōu)化相比,您可能更喜歡可讀性。
但是,如果您的應(yīng)用程序?qū)\行時敏感,并且您的列表很大并且這些小檢查正在累加,那么您可能想要執(zhí)行上述操作。

TA貢獻1818條經(jīng)驗 獲得超3個贊
如果您擔(dān)心的是獲得每個價值的fooService.getFooList()調(diào)用n時間,請f忽略該想法。這將調(diào)用getFooList()一次并迭代其結(jié)果。
例如在以下代碼段中:
class Ideone
{
private static List<String> list = Arrays.asList("A", "B", "C");
public static void main (String[] args) throws java.lang.Exception
{
for(String f : getFooList()){
System.out.println(f);
}
}
private static List<String> getFooList() {
System.out.println("getFooList called");
return list;
}
}
getFooList called僅打印一次,這表明該方法getFooList()僅被 for 循環(huán)調(diào)用一次。之后,打印A, B, C,對從方法調(diào)用獲得的元素進行迭代。
所以,在效率方面,它是相同的直接調(diào)用吸氣劑或?qū)⑵浞峙浣o一個變量,并利用該用于執(zhí)行迭代。
添加回答
舉報