2012-08-30 356 views
2

我的代碼是將RSS feeds添加到列表中 - 並且代碼最初只是從列表中的第一個位置拉出一個feed,然後添加這個對象到另一個列表。JAVA-如何從for循環訪問FOR循環中的變量

這是原代碼:

public static List<Feed> getFeedsFromXml(String xml) { 
     Pattern feedPattern = Pattern.compile("<feed>\\s*<name>\\s*([^<]*)</name>\\s*<uri>\\s*([^<]*)</uri>\\s*</feed>"); 


     Matcher feedMatch = feedPattern.matcher(xml); 
     while (feedMatch.find()) { 
      String feedName = feedMatch.group(1); 
      String feedURI = feedMatch.group(2); 
      feeds.add(new Feed(feedName, feedURI)); 
     } 

     return feeds; 
} 

@POST 
@Consumes(MediaType.APPLICATION_XML) 
@Produces(MediaType.APPLICATION_XML) 
public String addXmlFeed() throws IOException 
{ 
    int i = 0; 
    String stringXml = "<feed><name>SMH Top Headlines</name><uri>http://feeds.smh.com.au/rssheadlines/top.xml</uri></feed><feed><name>UTS Library News</name>"; 
    getFeedsFromXml(stringXml); 
    Feed f = (Feed) feeds.get(0); 
    feedList.add(f); 
    String handler = "You have successfully added: \n"; 
    String xmlStringReply = "" + f + "\n"; 

    feedList.save(feedFile); 
    return handler + xmlStringReply; 

} 

一切都進行得很好,然後我決定實現一個for循環處理一個以上飼料的添加到列表中,我嘗試了以下(

@POST 
@Consumes(MediaType.APPLICATION_XML) 
@Produces(MediaType.APPLICATION_XML) 
public String addXmlFeed() throws IOException 
{ 
    int i = 0; 
    String stringXml = "<feed><name>SMH Top Headlines</name><uri>http://feeds.smh.com.au/rssheadlines/top.xml</uri></feed><feed><name>UTS Library News</name>"; 
    getFeedsFromXml(stringXml); 
    for (Feed feed: feeds) 
    { 
     Feed f = (Feed) feeds.get(i++); 
     feedList.add(f); 
     String handler = "You have successfully added: \n"; 
     String xmlStringReply = "" + f + "\n"; 
    } 

    feedList.save(feedFile); 
    return handler + xmlStringReply; 

} 

現在,我敢肯定,這是一個基本的問題,但現在在該行:

return handler + xmlStringReply; 
只對有問題的第二種方法)的代碼3210

handlerxmlStringReply無法解析爲變量,因爲它們在FOR LOOP內。

有沒有簡單的解決方法呢?

回答

11

這兩個變量的範圍僅限於for循環。要訪問它們的外循環,就需要通過在循環之前宣佈他們增加範圍:

String handler = ""; 
String xmlStringReply = ""; 
for (Feed f: feeds) { 
    feedList.add(f); 
    handler = "You have successfully added: \n"; 
    xmlStringReply = "" + f + "\n"; 
} 

feedList.save(feedFile); 
return handler + xmlStringReply; 

而且,當前的代碼將覆蓋串在每個循環的價值,而你可能是指以連接值。在這種情況下,您可以使用StringBuilder代替字符串連接:

StringBuilder xmlStringReply = new StringBuilder("You have successfully added: \n"); 
for (Feed f: feeds) { 
    feedList.add(f); 
    xmlStringReply.append(f + "\n"); 
} 

feedList.save(feedFile); 
return xmlStringReply.toString(); 
+0

請注意,您可能不想覆蓋這些值,但會將一些信息附加到字符串中。 –

+0

@StefanNeubert好點 - 我錯過了'+'的缺席。 – assylias

+0

Downvoter關心評論? – assylias

2

因爲現在它們已經超出了範圍。

除了原來的錯誤 - 你可以很容易地解決使用其他建議,我想建議你不應該使feeds作爲實例變量。我可以看到你的方法getFeedsFromXml()正在返回列表。所以,我認爲如果在該方法中定義該變量會更好。然後,調用方法類似,

List<Feed> feeds = getFeedsFromXml(stringXml); 

或者在情況下,這不會給你所期望的行爲,那麼你應該將方法重命名爲,loadFeedsFromXml()將其作爲實例變量可能會導致線程問題

現在,試圖改善你的循環,

StringBuilder xmlStringReply = new StringBuilder("You have successfully added: \n"); 
for (Feed feed: feeds) { 
    feedList.add(feed); 
    xmlStringReply.append(f + "\n"); 
} 

feedList.save(feedFile); 
return xmlStringReply.toString(); 

而且,我發現你的feedList也是一個實例變量。這又會導致線程問題,因爲它聽起來不可變或無狀態。同步這些方法會給你帶來性能問題。看看你是否可以在本地使用這種方法。 經驗法則是儘量縮小可變範圍

+2

嘿,夥計們。這個答案有什麼問題?我想你們這些人不能等。 –

+0

+1並感謝您的編輯。 – assylias

+0

我低估了原因,因爲原來的答案沒有意義。我已經刪除了downvote。 – Nick

2

您需要將結果累加到一個變量中。我正在使用StringBuilder,因爲它使字符串串聯效率更高。

@POST 
@Consumes(MediaType.APPLICATION_XML) 
@Produces(MediaType.APPLICATION_XML) 
public String addXmlFeed() throws IOException 
{ 
    String stringXml = "<feed><name>SMH Top Headlines</name><uri>http://feeds.smh.com.au/rssheadlines/top.xml</uri></feed><feed><name>UTS Library News</name>"; 
    getFeedsFromXml(stringXml); 

    StringBuilder replyBuilder = new StringBuilder("You have successfully added: \n"); 
    for (Feed feed : feeds) 
    { 
     feedList.add(feed); 

     String xmlStringReply = feed + "\n"; 
     reployBuilder.append(xmlStringReply); 
    } 

    feedList.save(feedFile); 
    return replyBuilder.toString();  
} 
+0

@Peter Minchev,優秀,非常有幫助謝謝。只有一個問題,在你的代碼中,我假定String變量「xmlStringReply」應該在FOR循環之外以及String變量「Handler」之外聲明。 這是正確的嗎? – AlexM

+0

@AlexM不,它不需要,因爲它只在循環中使用。 – assylias

+0

@AlexM - 'Handler'應該在外面,但'xmlStringReply'沒有必要。 –

2

問題需要回答是「我要回,如果我補充幾個進?做什麼」。

也許你想回到"You have successfully added : feed1 feed2 feed3\n"

在這種情況下,代碼:

  StringBuilder response = new StringBuilder("You have successfully added: "); 
      for (Feed feed: feeds) 
       { 
        feedList.add(feed); 
        response.append(f.toString()).append(" "); 
       } 
      feedList.save(feedFile); 
      return response.toString(); 

順便說,你feedf變量是一樣的,並redondant!

不要寫:

int i = 0;  
for (Feed feed: feeds) 
{ 
    Feed f = (Feed) feeds.get(i++); 
    feedList.add(f); 
} 

for (Feed feed: feeds) 
{ 
    feedList.add(feed); 
} 
+0

這是有道理的,它被編碼爲先前的原因是最初的功能要求是我只從列表中提取FIRST feed並添加它,現在下一個功能要求是添加一個機制接受多個Feed。 我會調查你的迴應。 – AlexM

0

一個好的經驗法則是查看範圍是這樣的:所創建/間實例

{ //This is a constructor 

    int i; 

} // This is a deconstructor 

什麼捲髮只能在捲髮裏面生存。無論何時使用變量和循環:

for(int i = 0; i < 10; i++){ 

//some code here 
} // after this curly i is no longer in scope or accessible.