Is it a good way to empty an arrayList?

Hello,

I use an arrayList to store points making a polyline and I want to replace the points each time I press the mouse button.

Instead of using a for loop to iterate through the arrayList and remove the items one by one using the remove method I recreate the arrayList instead. Is it a good practice or not?

int numPoints = 10;

 ArrayList<Point> MesPoints = new ArrayList();

void setup() {
  size(900, 900);
  background(0);
}

void draw() {
  background(0);
  stroke(255,0,0);
  strokeWeight(5);
  for (int i = 0; i < MesPoints.size()-1; i++) {
    Point oldp = MesPoints.get(i);
    Point newp = MesPoints.get(i+1);
    line(oldp.pos.x, oldp.pos.y, newp.pos.x, newp.pos.y);
  }

}

void mousePressed() {
  MesPoints = new ArrayList(); // important! Recreation of the arraylist to clean it!
  for (int i = 0; i < numPoints ; i++) {
    Point np=new Point();
    np.pos=new PVector(random(width), random(height));
    MesPoints.add(np);
  }
}

class Point {
  PVector pos; 
}

Hello @amundsen,

:)

2 Likes

Haha. Great @glv! But I wonder if recreating the arrayList is more efficient or not as both clear() and removeAll() imply some iteration whereas a full recreation doesn’t I guess.

Related topic here:

:)

2 Likes

B/c I prefer to declare my variables w/ keyword final as much as possible I only use clear() for it:

import java.util.List;

static final int DOTS = 10;
final List<PVector> dots = new ArrayList<PVector>(DOTS);

void setup() {
  size(800, 600);
  noLoop();

  mousePressed();

  stroke(#FF0000);
  strokeWeight(5);
}

void draw() {
  background(0);
  
  int idx = 0;
  PVector pos = dots.get(idx);
  float x = pos.x, y = pos.y;

  while (++idx < DOTS) {
    pos = dots.get(idx);
    line(x, y, x = pos.x, y = pos.y);
  }
}

void keyPressed() {
  mousePressed();
}

void mousePressed() {
  dots.clear();

  for (int i = 0; i < DOTS; ++i) {
    dots.add(new PVector(random(width), random(height)));
  }

  redraw();
}

Main advantage of keeping around the same container is to spare the garbage collector from dealing w/ all discarded previous containers.

However, giving the container is always size() = DOTS, we don’t really need method clear().

We can simply refresh each PVector w/ randomized new values via method set():

import java.util.List;

static final int DOTS = 10;
final List<PVector> dots = new ArrayList<PVector>(DOTS);

void setup() {
  size(800, 600);
  noLoop();

  for (int i = 0; i < DOTS; ++i) dots.add(new PVector());
  mousePressed();

  stroke(#FF0000);
  strokeWeight(5);
}

void draw() {
  background(0);

  int idx = 0;
  PVector pos = dots.get(idx);
  float x = pos.x, y = pos.y;

  while (++idx < DOTS) {
    pos = dots.get(idx);
    line(x, y, x = pos.x, y = pos.y);
  }
}

void keyPressed() {
  mousePressed();
}

void mousePressed() {
  for (final PVector pos : dots) pos.set(random(width), random(height));
  redraw();
}

Actually, we can simplify it further by just using a regular Java array for such cases:

static final int DOTS = 10;
final PVector[] dots = new PVector[DOTS];

void setup() {
  size(800, 600);
  noLoop();

  for (int i = 0; i < DOTS; dots[i++] = new PVector());
  mousePressed();

  stroke(#FF0000);
  strokeWeight(5);
}

void draw() {
  background(0);

  int idx = 0;
  PVector pos = dots[idx];
  float x = pos.x, y = pos.y;

  while (++idx < DOTS) {
    pos = dots[idx];
    line(x, y, x = pos.x, y = pos.y);
  }
}

void keyPressed() {
  mousePressed();
}

void mousePressed() {
  for (final PVector pos : dots) pos.set(random(width), random(height));
  redraw();
}
1 Like