Question

I attempt to write programm that extracting all images from website(like wallpapers). I decided to make dinamic collection fore image links, but getByXPath method doesnt allow me to do this:

    HtmlPage currentPage = (HtmlPage) webClient.getPage(newURL("http://www.animewallpapers.com"));
    List<?> urls = new ArrayList<HtmlImage>();
    urls = currentPage.getByXPath("//img");
    for(int i = 0; i < 500; i++){
        currentPage = (HtmlPage) webClient.getPage(new URL(urls.get(i).toString()));
        List<?> tempListUrls = new ArrayList<HtmlImage>();
        tempListUrls = currentPage.getByXPath("//img");

Here I want to add tempListUrls to urls, but I can't. How do you suggest me to solve this problem?

Was it helpful?

Solution

It looks like what you are dealing with here is a mix generic and non-generic codde: there's your code (which obviously uses generics) and some (presumably third-party) code which apparently does not. The assignment

urls = currentPage.getByXPath("//img");

fails to compile if you declare the urls variable as List<HtmlImage> because it appears that getByXPath is returning an unparameterized List instance. The problem is that when you parameterize collection with '?' then compiler fills in '?' to the add method (and other methods, of course). So you get boolean add(? o) meaning the only objects the method now accepts as arguments must be of indeterminate type. Unfortunately, only null fits this requirement since only null is of indeterminate type.

This means that you must either use an unparameterized List object yourself, or you must cast from List to List<HtmlImage> in your code like this:

List<HtmlImage> urls = (List<HtmlImage>) currentPage.getByXPath("//img");

which will cause a compiler warning, but as long as you know that the returned list will only ever contain instances of HtmlImage or its subclasses then it's safe to do. You can use @SuppressWarnings("unchecked") in most Java compilers to avoid the warning.

As a side note: you are unnecessarily assigning new ArrayList<HtmlImage> () to urls and tempListUrls in your code and then reassigning those variables immediately which is inefficient. You can skip creating the unused ArrayList in both cases.

So your code might look something like this:

HtmlPage currentPage = (HtmlPage) webClient.getPage(newURL("http://www.animewallpapers.com"));
@SuppressWarnings("unchecked")
List<HtmlImage> urls = (List<HtmlImage>) currentPage.getByXPath("//img");
for(int i = 0; i < 500; i++){
    currentPage = (HtmlPage) webClient.getPage(new URL(urls.get(i).toString()));
    @SuppressWarnings("unchecked")
    List<HtmlImage> tempListUrls = (List<HtmlImage>) currentPage.getByXPath("//img");

I recommend avoiding @SuppressWarnings except when it affects only a single line of code, otherwise it can create a maintenance headache in the future.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top