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;

}

4

3 Answers 3

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));
Sign up to request clarification or add additional context in comments.

8 Comments

i need to split it into three Arraylists because i have to iterate over each of the three lists
@MarcRasmussen: so? you can iterate over a List just as easily as over an ArrayList.
i can't do foreach can i?
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.
@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).
|
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.

Comments

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)

1 Comment

"exclusive for toIndex". that is really good to know. Probably should have read the documentation on that one :p

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.