2012-08-30 247 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.