Whenever using ArrayList
, the method containsAll(collection)
runs in time \$\mathcal{O}(mn)\$, where \$n\$ is the size of ArrayList
and \$m\$ is the length of collection
. However, it relies only on equals(Object)
-method.
I have this subclass of ArrayList
that does the same in time \$\mathcal{O}(n)\$, but relies on hashCode()
as well.
My main question, should I do this optimization at expense of adding more requirements?
MyArrayList.java:
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
/**
* This class provides a faster {@link #containsAll(java.util.Collection) }
* method.
*
* @author Rodion "rodde" Efremov
* @version 1.6
* @param <E> the actual element type.
*/
public class MyArrayList<E> extends ArrayList<E> {
/**
* Returns {@code true} if this list contains all elements in {@code coll}
* and {@code false} otherwise.
*
* @param coll the collection to check for inclusion in this list.
* @return {@code true} if this list contains all elements in
* {@code coll}:
*/
@Override
public boolean containsAll(Collection<?> coll) {
Set<?> set = new HashSet<>(coll);
for (E element : this) {
if (set.contains(element)) {
set.remove(element);
if (set.isEmpty()) {
return true;
}
}
}
return false;
}
public static void main(final String... args) {
List<Integer> jdkList = new ArrayList<>();
List<Integer> myList = new MyArrayList<>();
for (int i = 0; i < 1000000; ++i) {
jdkList.add(i);
myList.add(i);
}
Random rnd = new Random();
Collection<Integer> coll = new ArrayList<>();
for (int i = 0; i < 1000; ++i) {
coll.add(rnd.nextInt(myList.size()));
}
// Uncomment for failing test.
//coll.add(-1);
long ta = System.currentTimeMillis();
boolean result = jdkList.containsAll(coll);
long tb = System.currentTimeMillis();
System.out.println("ArrayList.containsAll() in " + (tb - ta) + " ms. " +
"Result: " + result);
ta = System.currentTimeMillis();
result = myList.containsAll(coll);
tb = System.currentTimeMillis();
System.out.println("MyArrayList.containsAll() in " + (tb - ta) +
" ms. Result: " + result);
}
}