简体   繁体   English

JAVA - 如何从for循环外部访问FOR循环内的变量

[英]JAVA - How to access variables inside a FOR loop, from outside the for loop

My code is to add RSS feeds to a list - and the code originally was only to pull one feed from the first position in a list, and add this object to another list. 我的代码是将RSS提要添加到列表中 - 最初的代码只是从列表中的第一个位置提取一个提要,并将此对象添加到另一个列表中。

This was the original code: 这是原始代码:

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;

}

Everything was going well, and then I decided to implement a for loop for handling the adding of more than one feed to the list, and I tried the following (only the code for the second method in question): 一切进展顺利,然后我决定实现一个for循环来处理向列表添加多个feed,我尝试了以下(只有第二个方法的代码):

@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;

}

Now I'm sure this is a basic problem, but now in the line: 现在我确定这是一个基本问题,但现在在线:

    return handler + xmlStringReply;

handler and xmlStringReply cannot be resolved to a variable as they are within the FOR LOOP. handlerxmlStringReply无法解析为变量,因为它们在FOR LOOP中。

Is there any easy way around this? 这有什么简单的方法吗?

The scope of those 2 variables is limited to the for loop. 这两个变量的范围仅限于for循环。 To access them outside the loop, you need to increase their scope by declaring them before the loop: 要在循环外访问它们,您需要通过在循环之前声明它们来增加它们的范围:

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;

Also, your current code overwrites the value of your strings at each loop, whereas you probably meant to concatenate the values. 此外,您当前的代码会在每个循环中覆盖字符串的值,而您可能想要连接这些值。 In that case, you could use a StringBuilder instead of string concatenation: 在这种情况下,您可以使用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();

Because, now they became out of scope. 因为,现在它们已经超出了范围。

Beside the original error -- you can easily fix that using other suggestions, I would like to suggest that you should not make feeds as instance variable. 除了原始错误 - 您可以使用其他建议轻松解决这个问题,我建议您不要将feeds作为实例变量。 I can see your method getFeedsFromXml() is returning the list. 我可以看到你的方法getFeedsFromXml()返回列表。 So, I think it would have been better if you define that variable inside that method. 所以,我认为如果在该方法中定义该变量会更好。 And then, call the method like, 然后,调用方法,如,

List<Feed> feeds = getFeedsFromXml(stringXml);

Or in case, this doesn't give you the desired behaviour, then you should rename the method to something, loadFeedsFromXml() . 或者,如果这不能提供所需的行为,那么您应该将方法重命名为loadFeedsFromXml() Making that as instance variable may result in threading issues . 将其作为实例变量可能会导致线程问题

Now, trying to improve on your looping, 现在,尝试改进你的循环,

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();

Moreover, I found that your feedList is also a instance variable. 而且,我发现你的feedList也是一个实例变量。 And this again can cause threading issues, as it doesn't sound immutable or stateless. 这又会导致线程问题,因为它听起来不可变或无状态。 Synchronising the methods will give you performance issues. 同步方法会给您带来性能问题。 See if you can make it local to this method. 看看你是否可以将它作为本地方法。 A rule of thumb is to keep variable scope as narrow as possible . 一个经验法则是尽可能缩小变量范围

You need to accumulate the result into a variable. 您需要将结果累积到变量中。 I am using StringBuilder because it makes string concatenation efficient. 我正在使用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();    
}

The question you need to answer is "what do I want to return if I add several feeds ?". 需要回答的问题是“如果添加多个Feed,我想要返回什么内容?”。

Maybe you'd like to return "You have successfully added : feed1 feed2 feed3\\n" 也许您想要返回"You have successfully added : feed1 feed2 feed3\\n"

In that case, the code is : 在这种情况下,代码是:

            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();

By the way , your feed and f variables are just the same and redondant ! 顺便说一句 ,你的feedf变量是一样的和redondant!

Don't write : 不要写:

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

but

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

A good rule of thumb is to view scope like this: 一个好的经验法则是查看这样的范围:

 { //This is a constructor

  int i;

} // This is a deconstructor

anything that is created / instantiated between the curlies only lives inside the curlies. 在curlies之间创建/实例化的任何东西都只存在于curlies中。 Whenever your working with variables and loops: 每当你使用变量和循环时:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM