ListIterator tutorial
This post is for processing users who don't have a solid Java background. If you know Java, you may already know this stuff.
So, I don't know about you but I'm constantly finding myself creating ArrayLists or LinkedLists of Objects and then iterating through those lists in the draw() method. A great way to do to this is using the Foreach loop like... for(Circle c : circles)
But, what if you want to dynamically add and remove Objects from the list? What if you want to do so in the middle of iterating through the list? Java doesn't like this. It gets angry and throws ConcurrentModificationExceptions at you.
The solution to this is to use Iterator Objects. The one I like to use is the ListIterator class. So, what's an iterator? You can think of it as a variable that points to an Object in a list. Or more specifically, you can think of it as pointing to the space between two Objects in a list. When you create the ListIterator, it points to the space right before the first element in the list.
The ListIterator class has several methods, but here's the important ones:
hasNext() - This is a boolean method that tells you if there's another element in the list. Use this in a while() loop to iterate through the list.
next() - This is the method that returns the next element in the list, in other words, the element that is next to the space the iterator is pointing to. When you call next, the element is returned and the iterator moves to the next position. There's a catch with this one. You can't call next() unless you call hasNext() first, and you can only call next() once for each call to hasNext(). I guess that's to ensure there's always something there when you call next().
remove() - This must be called after a call to next(). What it does is remove the element from the list that was previously returned by next(). You can only call remove() once for each call to next().
add() - This method adds an Object into the list such that it is right before the element that will be returned by the next call to next(). Similarly to remove(), you can only call this once per call to next().
note: After you call next() you can call either add() or remove() only once. You cannot call one of each, just one overall.
The ListIterator class lets you iterate through lists backwards with hasPrevious() and previous() as well, but I'm not gonna go into that. For more info see the Javadoc.
EXAMPLE
Here's a little example that creates a bunch of balls in the middle of the screen and has them travel to the edge of the screen. When they are no longer visible they are removed from the list and new ones are added. Notice that you have to import java.util.ListIterator.
import java.util.ListIterator; ArrayList<Ball> balls; void setup() { size(500, 500); background(255); noStroke(); smooth(); balls = new ArrayList<Ball>(); for(int i = 0; i < 50; i++) { PVector p = new PVector(width/2, height/2); PVector v = new PVector(random(-5,5), random(-5, 5)); int filler = color((int) random(255), (int) random(255), (int) random(255)); int radius = (int) random(5,20); Ball b = new Ball(p, v, radius, filler); balls.add(b); } } void draw() { background(255); //our ListIterator for the balls collection is created by using the //listIterator() method of balls. ListIterator<Ball> it = balls.listIterator(); //we use the hasNext() method to loop through the list. while(it.hasNext()) { Ball b = it.next(); fill(b.filler()); ellipse(b.p.x, b.p.y, b.radius(), b.radius()); b.update(); //this looks to see if the Ball is off the screen and removes it if it is. //making use of the remove() method of our Iterator. if(b.p.x < 0 || b.p.x > width || b.p.y < 0 || b.p.y > height) { it.remove(); } } //This loop creates new Balls to replace the removed ones until the size of //Collection is back up to 50. while(balls.size() < 50) { PVector p = new PVector(width/2, height/2); PVector v = new PVector(random(-5,5), random(-5, 5)); int filler = color((int) random(255), (int) random(255), (int) random(255)); int radius = (int) random(5,20); Ball b = new Ball(p, v, radius, filler); balls.add(b); } } //This is the Ball class. //It has a position Vector p, and velocity Vector v. //Each Ball also maintains a radius and color. public class Ball { public PVector p; public PVector v; private final int radius; private final int filler; public Ball(PVector p, PVector v, int radius, int filler) { this.p = p; this.v = v; this.radius = radius; this.filler = filler; } public int radius() { return radius; } public int filler() { return filler; } public void update() { p.set(p.x + v.x, p.y + v.y, 0); } }
I hope this makes any sense whatsoever, and I hope if you didn't know about Iterators, that you do now and that you'll use them to do awesome things.
UPDATE
One thing I forgot to mention. You have to parameterize the ListIterator using angle brackets the same way that you would for an ArrayList or LinkedList. If you don't then when you call next() it will return objects of type Object, and you'll have to cast them to their specific type.










