注意:我真的不知道如何问我的问题,所以我的标题可能没有任何公正。如何通过ArrayList <SubClass> as ArrayList <BaseClass>
我开始写一个RSS解析器。我希望用户能够指定他们想要的信息,并且我的parseInnerXmlByTag方法将返回该类型的ArrayList。问题是不同的标签具有不同的属性,这意味着我将不得不为每种类型的标签(“项目”,“通道”,“条目”...)创建类别。所以我决定创建一个空的RSSElement类。然后我创建了一个扩展它的RSSItem类。所以我的parseInnerXmlByTag现在返回一个ArrayList < RSSElements>。 我的目标是让用户只调用一个方法来指定他们想要的信息。假设他们指定了“item”,该方法应该返回ArrayList < RSSItem>。
但是像这样的生产线将无法工作,因为这两种类型不techically有关系:
ArrayList<RSSElement> data = (method returning ArrayList<RSSItem>)
我有麻烦缠绕我的头周围通配符和亚型,所以我在想,如果有人可以看看我到目前为止给我的想法。这里是我的代码
public class RSSParser {
public static ArrayList<RSSElement> parseInnerXmlByTag(String in, String tag)
throws XmlPullParserException, IOException{
ArrayList<RSSElement> data = new ArrayList<>();
StringReader input = new StringReader(in);
try{
XmlPullParser parser = Xml.newPullParser();
parser.setInput(input);
parser.nextTag();
data = readFeed(parser, tag);
}
finally {
input.close();
return data;
}
}
/*
Returns an ArrayList of parsed RSSElements specified by "tag"
*/
private static ArrayList<RSSElement> readFeed(XmlPullParser parser, String tag)
throws XmlPullParserException, IOException{
ArrayList<RSSElement> data = new ArrayList<>();
int event = parser.getEventType();
//Parse until input is consumed
while(event != XmlPullParser.END_DOCUMENT){
switch (event){
case XmlPullParser.START_TAG:
if(parser.getName().equalsIgnoreCase(tag)){
RSSItem item = RSSItem.processItem(parser);
data.add(RSSItem.processItem(parser));
}
break;
}
event = parser.next();
}
return data;
}
public static abstract class RSSElement{
//Private constructor prevents instantiation
private RSSElement(){}
}
public static class RSSItem extends RSSElement{
String title = "";
String description = "";
public RSSItem(String t, String d){
title = t;
description = d;
}
@Override
public String toString() {...}
/*
Parses an RSS item tag into a container RSSItem (ONLY GRABS TITLE RIGHT NOW)
*/
protected static RSSItem processItem(XmlPullParser parser)
throws XmlPullParserException, IOException{
String currentTag = "";
String title = "";
/*
while end tag hasn't been reached yet:
reaching the end tag means parser.getEventType == END_TAG && parser.getName = tag
*/
while(!(parser.next() == XmlPullParser.END_TAG && parser.getName().equalsIgnoreCase("item"))){
Log.i("rssparser", "process entry");
if(parser.getEventType() == XmlPullParser.START_TAG){
currentTag = parser.getName();
}
else if(parser.getEventType() == XmlPullParser.TEXT && currentTag.equalsIgnoreCase("title")){
title = parser.getText();
break;
}
}
return new RSSItem(title, description);
}
}
}
现在这段代码完成并返回ArrayList。另外我知道它是根据我的日志正确解析RSSItems。 但这里是我用它(又名原因,我在这里发帖)
@Override
public void onResponse(String response){
ArrayList<? extends RSSParser.RSSElement> items = null;
try {
items = RSSParser.parseInnerXmlByTag(response, "entry");
}...
if(items != null) {
for(int i = 0; i < items.size(); i++){
//****DOESNT WORK****
redditOutputTextView.append(items.get(i).title + "\n");
}
}
else redditOutputTextView.setText("Items null");
}
该行存在显然无法工作,因为它不知道它的RSSItems的数组。所以希望有人能够弄清楚我想要做什么并提出一些建议。
已修复它!那么这个和我注意到的事实的结合,我在一行中调用了processItem方法两次,可能创建了空对象。谢了哥们。 – sadelbrid