注意:我真的不知道如何問我的問題,所以我的標題可能沒有任何公正。如何通過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