4.5 Lists of Actors
Getting a List of Actors in Greenfoot
Unit 4: Loops and Collections of Actors · Lesson 4.5 · about 30 minutes · no coding experience needed
So far you have dealt with actors one at a time. A wave of twenty enemies needs a way to ask "how many are left" and "do this to all of them", and there is one trap in doing so that throws an exception with a genuinely frightening name.
What you will be able to do
- Get a list of every actor of a kind
- Count how many are in the world
- Remove actors from a list safely
Words you will need
- List
- In plain words A numbered collection of things that knows how big it is.
- More precisely java.util.List, an ordered collection with a size.
- size()
- In plain words How many are in it.
- More precisely The number of elements currently in the list.
Build it step by step
Every step below leaves a scenario that compiles and runs. If you stop halfway you will have something that works, not something broken. Follow along in Greenfoot rather than reading straight through.
-
Step 1
On your screen A world containing several enemies with a count displayed.
Listenemies = getObjects(Enemy.class); int howMany = enemies.size(); `getObjects(Enemy.class)` hands back every Enemy currently in the world.
`List
` is the type. Read the angle parentheses as "of": a List of Enemy. It is new punctuation but not a new idea. `.size()` tells you how many. Note the parentheses: it is a method, not a field, unlike the array length you meet in Unit 5. That inconsistency is Java's fault, not yours, and it catches everybody.
-
Step 2
On your screen A wave-complete check triggered when the enemy list is empty.
if (getObjects(Enemy.class).size() == 0) { startNextWave(); }A real use, and it goes in the WORLD's act() method. Yes, the world has one too, and it runs every frame just like an actor's.
This is the natural home for anything about the game as a whole: how many enemies are left, whether the level is finished, what the score is.
-
Step 3
On your screen A loop over a list using an index.
Listenemies = getObjects(Enemy.class); for (int i = 0; i < enemies.size(); i++) { Enemy e = enemies.get(i); e.turn(180); } Looping over a list with the counting loop from 4.2.
`enemies.get(i)` fetches the one at position i. Positions start at 0 and the last is size() minus 1, which is why `i < enemies.size()` is exactly right.
The next lesson shows a shorter way when you do not need the index.
-
Step 4
On your screen A ConcurrentModificationException stack trace next to the corrected copy-first version.
// THROWS ConcurrentModificationException for (Enemy e : getObjects(Enemy.class)) { removeObject(e); } // SAFE: remove them all at once instead removeObjects(getObjects(Enemy.class));Here is the trap, and it is worth meeting before you write it by accident.
Removing actors from the world while looping over the list you got FROM the world is like tearing pages out of a book while reading it. Java notices and throws ConcurrentModificationException.
The name is alarming and the fix is one line. `removeObjects(...)` takes the whole list and clears it in one go. When you need finer control, collect what you want to remove into a separate list first, then remove them after the loop has finished.
Mistakes almost everyone makes here
These are the wrong ideas students actually build at this point. Read them even if you think you understand, because a wrong idea you have not noticed is the expensive kind.
Common wrong idea size is a field, like length.
What is actually true It is a method: `size()` with parentheses.
Why it matters Java is genuinely inconsistent here, and Unit 5 uses `length` with no parentheses.
Common wrong idea getObjects returns actors that have been removed.
What is actually true It returns what is in the world RIGHT NOW.
Why it matters The list is a snapshot, which is exactly why modifying during iteration is unsafe.
Common wrong idea ConcurrentModificationException means the code is badly broken.
What is actually true It means you changed a collection while looping over it. One-line fix.
Why it matters The name frightens beginners into rewriting far more than they need to.
Common wrong idea Only actors can have an act() method.
What is actually true The world has one too, and it runs every frame.
Why it matters Without knowing this, game-wide logic gets crammed into an actor where it does not belong.
Check your understanding
Answer these before moving on. They are graded instantly and you can retry.
-
1. What does `getObjects(Coin.class)` return?
-
2. How do you find out how many enemies are in the world?
-
3. A list has 4 items. What is the last valid index?
-
4. What causes ConcurrentModificationException here?
-
5. Where does game-wide logic like "are all enemies dead" belong?
Fill in the code
In the world act() method, start the next wave when no enemies are left.
public void act()
{
if (getObjects(Enemy.class).() 0)
{
startNextWave();
}
}
Stuck? Open a hint for each blank
- Blank 1: The method that reports how many are in a list.
- Blank 2: Test for equality, which needs two characters.
Lesson quiz
This one counts toward your progress. Take it when the section above makes sense.
-
1. `List
` is read as: -
2. How do you safely remove every enemy?
-
3. getObjects returns:
-
4. Why does the world have an act() method?
The short version
- getObjects(Thing.class) hands back a List of everything of that kind in the world.
- size() is a METHOD with parentheses. Indexes run 0 to size() minus 1.
- The world has an act() too, and game-wide logic belongs there.
- Never remove from the world while looping over its list. Use removeObjects, or collect first.
If you get stuck
These pages cover the problems that come up most often in this lesson. Opening one is not cheating and it is not counted against you.
Get in Touch
Whether you're a student, parent, or teacher — I'd love to hear from you.
Just want free AP CS resources?
Enter your email below and check the subscribe box — no message needed. Students get daily practice questions and study tips. Teachers get curriculum resources and teaching strategies.
Message Sent!
Thanks for reaching out. I'll get back to you within 24 hours.
Prefer email? Reach me directly at [email protected]