2011-03-16 76 views
1

我可以使用iterable遍歷列表一遍又一遍?當我使用ArrayList,我可以遍歷列表一次又一次在「foreach」,但是當我使用迭代作爲hadoop(分佈式計算框架)函數中的參數時,只有第一次我可以遍歷迭代,當我再次使用foreach,它沒有用。 例如:我可以使用iterable在「foreach」中一遍又一遍地遍歷列表嗎?

public void reduce(Text key, Iterable<Text> values, Context context) 
throws IOException, InterruptedException { 

float all=0; 
String resultKey; 
float resultValue; 
ArrayList<String> valuelist=new ArrayList<String>(); 

for (Text text : values) { 
    valuelist.add(text.toString()); 
} 

for (String text : valuelist) { 
    String[] contents=text.toString().split(" "); 
    if(contents.length==1) 
    { 
     all=Float.parseFloat(contents[0]); 
     break; 
    } 
} 

if(all==0) 
{ 
    return; 
} 

for (String text : valuelist) { 
    String[] contents=text.toString().split(" "); 

    if(contents.length>1) 
    { 
     resultKey=contents[0]+" "+key.toString(); 
     resultValue=Float.parseFloat(contents[1])/all; 

     context.write(new Text(resultKey), new Text(resultValue+"")); 
    } 
} 
} 

-----我必須將它保存在ArrayList中第一個... 在我的理解,只的foreach需要一個迭代,爲什麼ArrayList中就可以了,但是參數不能? 感謝您閱讀這麼多。

回答

3

這對Iterable來說並不是一個問題,但也許這是由框架傳遞給該方法的具體實現類的問題。如果你仔細想想,當你調用next()時,這個類可能通過網絡將Iterable的每個元素都拉出來。這可以解釋爲什麼你不能再運行它。如果這真的是你需要做的,保存每個元素是一個很好的解決方案。

+1

嚴格說來的'Iterable' ** **必須能夠提供一個'Iterator'連連(否則就沒有用,你可以只通過圍繞'Iterator')。 – 2011-03-16 12:49:17

+1

我同意這是預期的行爲,但是如果你看看Javadoc,你會發現對於接口來說,它所說的是「實現這個接口允許一個對象成爲」foreach「語句的目標,」並且它所說的iterator()方法是「返回一組類型爲T的元素的迭代器」。沒有*必須*任何地方,特別是,沒有跡象表明同一套T的元素必須每次返回。 – 2011-03-16 14:37:16

0

我認爲這個問題與迭代器是單向的一次性集合有關。從谷歌的集合FAQ:

一個迭代器表示元素的單向 滾動「流」,並 一個可迭代是任何可以 產卵獨立迭代器。 A 收藏是多少,遠遠超過 這個,所以我們只需要它時,我們 需要。 1

+2

但是'Iterable'應該可以迭代多次,通常情況下。 – 2011-03-16 12:34:57

+0

請參閱我對@Joachim Sauer的評論。 – 2011-03-16 14:37:57