We have a list of elements and have a very simplistic collision detection where we check every object against every other object.
The check is commutative, so to avo
For a linked list (which has slow index access), I think there is a way to do it without incurring in the O(n²) slowdown that Paŭlo mentioned. As long as you don't care about the order the list is visited, you can start the outer loop from the last element and iterate back, and start the inner loop from the first element and iterate forward until the two iterators meet. See iterRevIterator in the code below. The call to list.listIterator(list.size()) is fast because list is a LinkedList, i.e. a doubly-linked list, and accessing the last element does not require iterating through the list.
The difference is not enormous...
iterIndex: 384.59ms sum=29656666
iterIterator: 1.91ms sum=29656666
iterRevIterator: 1.55ms sum=29656666
but still significant.
import java.util.List;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.ListIterator;
public class TestIter {
public static int iterIndex(List list) {
int sum = 0;
for(int i = 0; i < list.size(); ++i) {
for(int j = i+1; j < list.size(); ++j) {
sum += list.get(i) * list.get(j);
}
}
return sum;
}
public static int iterIterator(List list) {
int sum = 0;
for(ListIterator outer = list.listIterator(); outer.hasNext() ; ) {
Integer oVal = outer.next();
for(ListIterator inner = list.listIterator(outer.nextIndex()); inner.hasNext(); ) {
sum += oVal * inner.next();
}
}
return sum;
}
public static int iterRevIterator(List list) {
int sum = 0;
for(ListIterator outer = list.listIterator(list.size()); outer.hasPrevious() ; ) {
Integer oVal = outer.previous();
for(ListIterator inner = list.listIterator(); inner.nextIndex() <= outer.previousIndex(); ) {
sum += oVal * inner.next();
}
}
return sum;
}
public static void main(String[] args) {
int size = 1000;
int rep = 100;
int sum = 0;
// List list = new ArrayList();
List list = new LinkedList();
for (int i = 0; i < size; ++i) {
list.add(i);
}
long startTime = System.currentTimeMillis();
for (int i = 0; i < rep; ++i) {
sum = iterIndex(list);
}
System.out.println("iterIndex: " + (float)(System.currentTimeMillis() - startTime)/rep + "ms sum=" + sum);
startTime = System.currentTimeMillis();
for (int i = 0; i < rep; ++i) {
sum = iterIterator(list);
}
System.out.println("iterIterator: " + (float)(System.currentTimeMillis() - startTime)/rep + "ms sum=" + sum);
startTime = System.currentTimeMillis();
for (int i = 0; i < rep; ++i) {
sum = iterRevIterator(list);
}
System.out.println("iterRevIterator: " + (float)(System.currentTimeMillis() - startTime)/rep + "ms sum=" + sum);
}
}