# Issues with removing an object

**URL:** <https://discourse.processing.org/t/issues-with-removing-an-object/28920>\
**Category:** Beginners\
**Created:** [March 28, 2021, 11:45am UTC](https://discourse.processing.org/t/issues-with-removing-an-object/28920 "2021-03-28T11:45:59Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![CodeMasterX](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/codemasterx/32/2942_2.png) [@CodeMasterX](https://discourse.processing.org/u/CodeMasterX)\
**Post date:** [March 28, 2021, 11:45am UTC](https://discourse.processing.org/t/issues-with-removing-an-object/28920/1 "2021-03-28T11:45:59Z")

</div>

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:

```auto
for(p obj : pro) { 
//updating & drawing the object
if(boolean) pro.remove(this) }

```

it did nothing. And when I replaced “this” with “obj” it spat out an error.

How do I do this without using the standard for loop `for(int i = 0; i < pro.size(); i++)` ?

> **Code**
>
> ```auto
> ArrayList<p> pro = new ArrayList<p>();
> float dir = 0, n = 7, defaultSpeed =5, angularAcceleration = 0.0001, maxAge = 5;
> void setup() { size(600,600); colorMode(HSB); }
> void draw() {
> background(0);
> if(frameCount % 15 == 0) for(float i = 0, a = TWO_PI/n; i < n; i++) pro.add(new p(300,300,defaultSpeed,0,angularAcceleration,dir+a*i,floor(i),maxAge));
> for(p obj : pro) {
> obj.update();
> obj.display();
> if(obj.age > obj.mA) println("I SHOULD BE DEAD");
> if(obj.x > width*1.1 || obj.x < -width*0.1 || obj.y > height*1.1 || obj.y < -height*0.1 || obj.age > obj.mA) pro.remove(obj);
> }
> println(pro.size());
> }
> class p {
> float x,y,mS,aS,aAcc,rot,src=0,age=0,mA=0;
> p(float x_, float y_, float mS_, float aS_, float aAcc_, float rot_, int source, float maxAge_) {
> x = x_; y = y_; mS = mS_; aS = aS_; aAcc = aAcc_; rot = rot_; src = source; mA = maxAge_;
> }
> void update() {
> age++;
> aS+=aAcc;
> rot+=aS;
> x += cos(rot)*mS;
> y += sin(rot)*mS;
> }
> void display() {
> fill(map(src,0,n,0,255),255,255); noStroke();
> circle(x,y,5);
> }
> }
> 
> ```

---

<div class="post-metadata">

**Author:** ![Schred](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/schred/32/13146_2.png) [@Schred](https://discourse.processing.org/u/Schred)\
**Post date:** [March 28, 2021, 1:48pm UTC](https://discourse.processing.org/t/issues-with-removing-an-object/28920/2 "2021-03-28T13:48:02Z")

</div>

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:

```auto
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** :

```auto
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.

---

<div class="post-metadata">

**Author:** ![CodeMasterX](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/codemasterx/32/2942_2.png) [@CodeMasterX](https://discourse.processing.org/u/CodeMasterX)\
**Post date:** [March 28, 2021, 2:31pm UTC](https://discourse.processing.org/t/issues-with-removing-an-object/28920/3 "2021-03-28T14:31:31Z")

</div>

> [@Schred](#):
>
> Instead you need to iterate over the list **backwards** :

It is not actually neccessary. I just used a regular old for loop and works just fine for my purpose

```auto
for(int i = 0; i < pro.size(); i++) {
  if(boolean) remove(i);
}

```

since everytime you erase an object it will shorten the list by 1.

I didn’t notice any imperfections in my program so far : D

But thank you for explaining all of it to me

---

<div class="post-metadata">

**Author:** ![Schred](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/schred/32/13146_2.png) [@Schred](https://discourse.processing.org/u/Schred)\
**Post date:** [March 28, 2021, 2:42pm UTC](https://discourse.processing.org/t/issues-with-removing-an-object/28920/4 "2021-03-28T14:42:59Z")

</div>

> [@CodeMasterX](#):
>
> I didn’t notice any imperfections in my program so far : D

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:

```auto
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.

---

<div class="post-metadata">

**Author:** ![jb4x](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jb4x/32/789_2.png) [@jb4x](https://discourse.processing.org/u/jb4x)\
**Post date:** [March 28, 2021, 3:14pm UTC](https://discourse.processing.org/t/issues-with-removing-an-object/28920/5 "2021-03-28T15:14:13Z")

</div>

As @Schred said, it is actually necessary.

Imagine you have the following list:

```auto
0: 0
1: 0
2: 1
3: 1
4: 2
5: 2

```

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:

```auto
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.

```auto
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.
