2016-01-21 282 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> { 

    } 
相关问题