2

I have an ArrayList with a size of 258

Now i wish to split this into three different ArrayLists for this i have created the following code:

    Integer start = (int) Math.floor((sitesToSearch.size() / 3));
    Integer middle = (int) Math.floor((sitesToSearch.size() / 2));
    Integer end = (int) Math.floor((sitesToSearch.size() / 1));

    ArrayList<String> crawl_list1 = (ArrayList<String>)tmp.subList(0, start);
    ArrayList<String> crawl_list2 = (ArrayList<String>)tmp.subList(start+1, middle);
    ArrayList<String> crawl_list3 = (ArrayList<String>)tmp.subList(middle+1, end);

Sadly this throws the following error:

Exception in thread "main" java.lang.ClassCastException: java.util.ArrayList$SubList cannot be cast to java.util.ArrayList

So how can i devide it into three smaller ArrayList

tmp declaration:

public ArrayList<String> getExternalLinks(ArrayList<String> rootDomains){
ArrayList<String> result = new ArrayList<String>();

Document doc = null;
/*
 * Check if root is valid
 * Find search the site for internal links
 */
for (String root : rootDomains) {
    if (!(root == null) || !root.isEmpty() ||!root.contains("#")) {
        try {
            doc = Jsoup.connect(root)
                    .userAgent("Mozilla")
                    .get();
            result.addAll(findExternalLinks(findInternalLinks(doc,root),root)); 
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
System.out.println(result.size());
return result;

}

Marc Rasmussen
  • 19,771
  • 79
  • 203
  • 364

3 Answers3

7

Simply use List<String> as the type of crawl_list1.

That's just an application of the general rule of "code against the interface".

There's really no good reason to require the return value of subList to be an ArrayList (and it doesn't make sense as subList returns a view onto the original ArrayList).

If you absolutely need ArrayList objects, then you need to copy the content into new ArrayList objects:

ArrayList<String> crawl_list1 = new ArrayList<String>(tmp.subList(0, start));
ArrayList<String> crawl_list2 = new ArrayList<String>(tmp.subList(start+1, middle));
ArrayList<String> crawl_list3 = new ArrayList<String>(tmp.subList(middle+1, end));
Community
  • 1
  • 1
Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
  • i need to split it into three Arraylists because i have to iterate over each of the three lists – Marc Rasmussen Nov 27 '13 at 14:00
  • 2
    @MarcRasmussen: so? you can iterate over a `List` just as easily as over an `ArrayList`. – Joachim Sauer Nov 27 '13 at 14:01
  • i can't do foreach can i? – Marc Rasmussen Nov 27 '13 at 14:03
  • Yes, you should code to interfaces as much as possible: Use `List` everywhere that a method returns the `List`. Only use `ArrayList` when you need to instantiate a new one yourself. – jalynn2 Nov 27 '13 at 14:03
  • @MarcRasmussen: Haven't I just said that you can do exactly that? Have you tried it? You can use foreach with every `Iterable` (which includes `Collection` which includes `List`). – Joachim Sauer Nov 27 '13 at 14:03
  • @MarcRasmussen: you should be able to replace every `ArrayList` in your code simply with `List` (except where you do `new ArrayList()`). – Joachim Sauer Nov 27 '13 at 14:05
  • @JoachimSauer oh yeah i can :D lol had the wrong import! what did you mean about the excluded thing? – Marc Rasmussen Nov 27 '13 at 14:06
  • @MarcRasmussen: you can't do `new List()` because `List` is an interface. That's the only place where you still need to use `new ArrayList()` even if you code against the interface. In all other places, you should simply use `List` instead of `ArrayList`. – Joachim Sauer Nov 27 '13 at 14:07
2

Look at the javadoc for ArrayList.subList(). It doesn't return an ArrayList. It returns a List. There's no reason to cast this list to an ArrayList. It's a list, and that's all you need to know:

List<String> crawl_list1 = tmp.subList(0, start);
List<String> crawl_list2 = tmp.subList(start+1, middle);
List<String> crawl_list3 = tmp.subList(middle+1, end);

Also, you should check your indices, because the end index passed to subList is exclusive.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
1

.subList(fromIndex, toIndex) is inclusive for fromIndex and exclusive for toIndex. With the current code middle and start will never populate an ArrayList.

The below two are assumptions of the logic:

.subList(start, middle)

.subList(middle, end+1)

Mason T.
  • 1,567
  • 1
  • 14
  • 33