rather than using ArrayList's contains(Object o), use pruning to avoid duplicates, much faster