There are lots of variations on this pattern. We can use almost any data structure for the collection.
Animal[] animals = new Animal[numberOfAnimals]; ⋮ for (int i = 0; i < numberOfAnimals; ++i) System.out.println (animals[i].name() + " " + animals[i].eats());
class ListNode {
Animal data;
ListNode next;
}
ListNode head; // start of list
⋮
for (ListNode current = head; current != null; current = current.next)
System.out.println (current.name() + " " + current.eats());
Again, notice the complete lack of *
or
->
operators that, as C++ programmers, we are used to
seeing as our cues that we are dealing with pointers.
ArrayList<Animal> animals = new ArrayList<Animal>();
⋮
for (Animal a: animals) {
System.out.println (a.name() + " " + a.eats());
}
Take note of the special syntax of this for
loop. For most Java container types, we can iterate through all
elements in the container by simply declaring the loop variable
(Animal a
) and then, after a ":", naming the container
(animals
).
Look also at the rather template-like declaration of the
animals
container. This is a fairly recent addition
to Java. Older Java code would leave out the part within the angle
brackets, in which case we would have to treat animals as a container
of Object
s, not Animal
s.
ArrayList animals = new ArrayList();
⋮
for (Object obja: animals) {
Animal a = (Animal)obja;
System.out.println (a.name() + " " + a.eats());
}
The downcast in the highlighted statement is required because
the loop variable, obja
, is of type
Object
and therefore does not support the
name()
and eats()
functions.
In the Forum: