2016-01-21 170 views
0

我正在學習java中的泛型並遇到此問題。將參考類型作爲參數傳遞並使用泛型

我有一個天氣界面。 EarthQuakeVirginiaWeather是實現Weather接口的兩個類。這兩個類都有一個靜態方法 - "parseData",它解析來自原子提要的數據。 Main類中的getFeeds方法有一個參數"String type",我用它來找出應該調用哪個類的方法。 任何人都可以請幫助我瞭解泛型是否可以用來使代碼更清潔。我可以將類類型作爲參數傳遞給方法,並使用該類類型在適當的類中調用parseData方法。 我試圖做 list.add(T.parseData((Element) nl.item(i))); 但得到:

的方法parseData(元)是未定義的類型T

public class Main { 

public static void main(String[] args) { 
    List<EarthQuake> quakes = getFeeds("http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.atom", "quakes"); 
    List<VirginiaWeather> weather = getFeeds("http://alerts.weather.gov/cap/va.php?x=0", "weather"); 
    //Get Earthquake data 
    System.out.println("Earthquake data"); 
    for (EarthQuake e: quakes) 
     System.out.printf("%s\t%s\t%f\t%s\n",(e.getDate()),e.getLocation(),e.getMagnitude(),e.getDetails()); 
    //Get Virginia weather data 
    System.out.println("Virginia Weather"); 
    for (VirginiaWeather vw: weather) 
     System.out.printf("%s\t%s\t%s\t%s\t%s\n",vw.getUpdated(),vw.getTitle(),vw.getEvent(),vw.getEffective(),vw.getExpires()); 
} 


private static <T> List<T> getFeeds(String url, String type) { 
    List<T> list = new ArrayList<>(); 
    try { 
     URL usgsUrl = new URL(url); 
     URLConnection urlConnection = usgsUrl.openConnection(); 
     HttpURLConnection httpConnection = (HttpURLConnection) urlConnection; 
     int response = httpConnection.getResponseCode(); 

     if(response == HttpURLConnection.HTTP_OK) 
     { 
      InputStream in = httpConnection.getInputStream(); 

      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
      DocumentBuilder db = dbf.newDocumentBuilder(); 

      Document document = db.parse(in); 
      Element element = document.getDocumentElement(); 
      NodeList nl = element.getElementsByTagName("entry"); 

      if(nl != null && nl.getLength() > 0) 
       for(int i =0 ; i<nl.getLength() ; i++) 
       { 
        if(type.equals("quakes")) 
        { 
         list.add((T) EarthQuake.parseData((Element) nl.item(i))); 
        } 
        if(type.equals("weather")) 
        { 
         list.add((T) VirginiaWeather.parseData((Element) nl.item(i))); 
        } 
       } 
     } 
    } catch (MalformedURLException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } catch (ParserConfigurationException e) { 
     e.printStackTrace(); 
    } catch (SAXException e) { 
     e.printStackTrace(); 
    } 
    finally{ 

    } 
    return list; 
} 

} 
+2

'類型==「地震」'EUH這不是好辦法 – 2016-01-21 17:30:10

+0

什麼RC是,你應該比較使用'等於()'對象 - 和字符串對象。 – Thomas

+0

Java泛型有點奇怪,因爲類型參數實際上並未綁定到類上,這就是爲什麼您會看到像JAXB這樣的東西需要java.lang.Class以及Generic類型。實用的方法是定義一個將文本轉換爲元素的接口;深奧的是使用反射從類中獲取類方法並調用它。 – Mark

回答

2

我會使用打字工廠。首先創建一個接口:

interface WeatherDataFactory<T> { 
    T parse(Element element); 
} 

然後再編寫具體的天氣數據工廠:

class VirginiaWeatherDataFactory implements WeatherDataFactory<VirginiaWeather> { 
    @Override 
    public VirginiaWeather parse(final Element element) { ... } 
} 

然後你getFeeds方法是這樣的:

private static <T> List<T> getFeeds(String url, WeatherDataFactory<T> factory) { 
    ... 
    if(nl != null && nl.getLength() > 0) { 
     for(int i =0 ; i<nl.getLength() ; i++) { 
      list.add(factory.parse(nl)); 
     } 
    } 
} 

順便說一句,大多數實現NodeList#item(int)表現得像一個鏈表,因爲整個列表必須被遍歷得到元素n。如果列表很大,你的程序將會非常慢。

+0

謝謝,如果使用NodeList.item(i)會很慢,你可以請建議一種替代方法 –

+0

@BKVP Google「DOM vs SAX」。您正在使用DOM。 –

1

爲什麼不使用Java 8的設施?

private static <T> List<T> getFeeds(String url, Function<Element, T> parser) { 
    // [..snip..] 
    for(int i =0 ; i<nl.getLength() ; i++) { 
     list.add(parser.call((Element) nl.item(i))); 
    } 
    // [..snip..] 
} 

你使用這樣的:

List<EarthQuakes> eq = getFeeds("http://....", EarthQuake::parseData); 
List<VirginiaWeather> eq = getFeeds("http://....", VirginiaWeather::parseData); 

這可能是在長期更加有用的管理解析工廠類,而不是合併數據表示和在同一類解析。

0

您可以使用輸入類。

public interface Weather<T>(){ 
     private static <T> List<T> getFeeds(String url, String type); 
} 

而其他類

public class EarthQuake implements Weather<EarthQuake> { 

    } 
相關問題