2

私のコードは、RSS フィードをリストに追加することです。元のコードは、リストの最初の位置から 1 つのフィードを取得し、このオブジェクトを別のリストに追加するだけでした。

これは元のコードでした:

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 ループを実装することに決め、次のことを試しました (問題の 2 番目のメソッドのコードのみ)。

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

handlerFOR LOOP 内にあるため、変数にxmlStringReply解決できません。

これを回避する簡単な方法はありますか?

4

5 に答える 5

11

これら 2 つの変数のスコープは 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

あなたが答える必要がある質問は、「複数のフィードを追加した場合、何を返したいですか?」です。

戻りたいのかもしれません"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 に答える
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さらに、 yourもインスタンス変数であることがわかりました。不変またはステートレスに聞こえないため、これもスレッドの問題を引き起こす可能性があります。メソッドを同期すると、パフォーマンスの問題が発生します。このメソッドに対してローカルにできるかどうかを確認してください。経験則として、変数のスコープはできるだけ狭くすることです。

于 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 に答える
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.
于 2012-08-30T13:41:46.053 に答える