2

我的代码是将 RSS 提要添加到列表中 - 代码最初只是从列表中的第一个位置拉出一个提要,然后将此对象添加到另一个列表中。

这是原始代码:

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;

handler并且xmlStringReply无法解析为变量,因为它们位于 FOR LOOP 中。

有什么简单的方法可以解决这个问题吗?

4

5 回答 5

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();
于 2012-08-30T08:37:42.090 回答
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的也是一个实例变量。这又会导致线程问题,因为它听起来不是不可变的或无状态的。同步这些方法会给您带来性能问题。看看你是否可以使它成为这个方法的本地。一个经验法则是尽可能缩小变量范围

于 2012-08-30T08:39:28.890 回答
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();    
}
于 2012-08-30T08:39:48.313 回答
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变量是一样的而且是多余的!

不要写:

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

for (Feed feed: feeds)
{
    feedList.add(feed);
}
于 2012-08-30T08:47:47.457 回答
0

一个好的经验法则是像这样查看范围:

 { //This is a constructor

  int i;

} // This is a deconstructor

在 curlies 之间创建/实例化的任何内容都只存在于 curlies 内。每当您使用变量和循环时:

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

 //some code here
 } // after this curly i is no longer in scope or accessible.
于 2012-08-30T13:41:46.053 回答