Summary of my question: I need a list that can quickly be iterated and sorted (either by sorting method or adding/removing object).
I’m coding a game in which there are a lot of “collision zones”, that are checked every frame. For optimization, I have a idea of sorting them depends on their X position. The problem is not all collision zones are static, because some of them can move around.
I have managed to handles all the changes, but to maintain the ArrayList (or ConcurrentLinkedQueue) sorted using Collections.sort() is too slow.
So I got a new idea: I may use a Tree, and whenever a zone’s X is changed, instead of sorting all elements again, I can just remove then re-add it from the tree. However, I think that adding and removing operator in TreeList are expensive too. Moreover, iterating through Tree is not as effective as ConcurrentLinkedQueue, LinkedList or ArrayList.
Please tell me if there is any built-in data structure that satisfy my need. If there is no such data structure, I intend to extend ArrayList class, override the add method to ensure the order (by using overload add(index, item). If you think this is the best way, please give me the best way to find the index. I already use BinarySearch but I think there is a bug:
@Override
public boolean add(T e) {
// Find the position
int left = 0;
int right = this.size() - 1;
int pos = right / 2;
if (e.compareTo(this.get(0)) <= 0) {
pos = 0;
} else if (e.compareTo(this.get(this.size() - 1)) >= 0) {
pos = this.size();
} else {
// Need: e[pos - 1] <= e[pos] <= e[pos + 1]
boolean firstCondition = false;
boolean secondCondition = false;
do {
firstCondition = this.get(pos - 1).compareTo(this.get(pos)) <= 0;
secondCondition = this.get(pos).compareTo(this.get(pos + 1)) >= 0;
if (!firstCondition) {
right = pos - 1;
pos = (left + right) / 2;
} else if (!secondCondition) {
left = pos + 1;
pos = (left + right) / 2;
}
} while (!(firstCondition && secondCondition));
}
this.add(pos, e);
return true;
}
I would use a tree set. if you need to allow duplicates you can use a custom comparator. while iterating a tree set is slightly slower than an array, adding and removing is much faster.
It appears you are doing an insertion sort which is O (n). an insert on a tree set is O (ln n)
IMHO The best way to store duplicates by using a
TreeMap<MyKey, List<MyType>>like thisIn this case, addition and removal is O(ln N);
You can allow “duplicates” is a TreeSet by defining all objects as different e.g.
As you can see this approach is ugly unless you have some way of making every object unique.