Hi!
I tried making a program, which makes use of the simplified for loop structure (for(p obj : pro){}) Inside of it, I made a condition stating that if the object obj is outside the screen or has age higher than maxAge, it is erased. However when I tried using:
First off, why should you use obj instead of this:
The keyword this always refers to the object that is executing the current piece of code. For example:
class MyClass {
int x = 0;
PVector vector = new PVector();
MyClass() {
// Access the variable 'x' of the PVector object
println(vector.x);
// Access the variable 'x' of this MyClass object.
// Most of the time, you don't need to use this.
println(this.x);
}
}
In your context it refers to the sketch itself, not the current object of the loop. That’s why you need to use obj.
The reason you can’t use a for-each loop in this case is because you are removing objects of the list while simultaneously trying to iterate over it. It just doesn’t work like that.
Instead you need to iterate over the list backwards:
for (int i = pro.size() - 1; i >= 0; i--) {
p obj = pro.get(i);
if (...)
// pro.remove(obj); <-- Slow
pro.remove(i); // <-- Faster
}
This way you make sure you don’t miss any elements because of their indices changing due to the removal of a preceding object.
That might very well be true, as the problem is probably very rare for your use case (it is highly unlikely that two objects that are next to each other in the list need to be removed the same frame), but it can still occur.
Take a look at and run the following piece of code:
void setup() {
// Create a new list
ArrayList<String> list = new ArrayList<String>();
// Fill it with some example elements
for (int i = 0; i < 10; i++)
list.add(String.valueOf(i)); // String.valueOf turns an integer into a string
// Copy and loop over it forwards while removing
ArrayList<String> forwards = new ArrayList<String>(list);
for (int i = 0; i < forwards.size(); i++) {
println(forwards.get(i));
forwards.remove(i);
}
println();
// Copy and loop over it backwards while removing
ArrayList<String> backwards = new ArrayList<String>(list);
for (int i = backwards.size() - 1; i >= 0; i--) {
println(backwards.get(i));
backwards.remove(i);
}
}
As you can see, if you iterate over the list forwards and remove an object, the next one will be skipped. The same applies to your loop, it just happens very rarely.
You want to remove from that array every value that is equal to 1.
If you loop forward, your code will be something like this:
for(int i = 0; i < array.size(); i++) {
if (array.get(i) = 1) {
array.remove(i)
}
}
So let’s run this by hand to see what it does.
First loop:
i = 0 ; Array(0) = 0 ==> Nothing happen
Second loop:
i = 1 : Array(1) = 0 ==> Nothing happen
Third loop:
i = 2 : Array(2) = 1 ==> We remove the third element of the list.
Now the list look like this:
0: 0
1: 0
2: 1
3: 2
4: 2
There is only 5 elements on list now
Fourth loop:
i = 3 : Array(3) = 2 ==> Nothing happen
Fifth loop:
i = 4 : Array(4) = 2 ==> Nothing happen
As you can see, we did get rid of one of the 1 but there is still one remaining.
The key moment to analyse is when we erase the element, it moves all the next elements by one. So the second 1 at position 3 is in position 2 after erasing the first 1. But since we already did the case i = 2, the next turn i = 3 so we miss the second 1.