Foreach isn’t a reach in pre-1.5
Developers living in the post 1.5 world are spoiled. With the very sweet foreach loop life is easy when you need to iterate through a list of objects. While us poor developers still living working with 1.4 or lower may not be able to totally match the 1.5 foreach loop we can certainly come close! While there are several ways to implement foreach functionality in 1.4 or below I will focus on the way I prefer to do it as I think it is the best way.
public class ForeachExample {
public static void main(String[] args) {
List personList = new ArrayList();Person joe = new Person();
joe.setFirstName("Joe");
joe.setLastName("Smith");Person cindy = new Person();
cindy.setFirstName("Cindy");
cindy.setLastName("Doe");personList.add(joe);
personList.add(cindy);for(Iterator iter = personList.iterator(); iter.hasNext();){
Person person = (Person)iter.next();
if(person.getFirstName().equals("Joe")){
iter.remove();
continue;
} else if(person.getFirstName().equals("Cindy")){
System.out.println(person.getFirstName() + " wins again!");
}
System.out.println(person.getFirstName());
}
//Prints "Cindy wins again!"
}}
Iterate? Can you please elaborate...
Ok so there is quite a bit happening there. First the for loop declaration. In the first section (called the initialization statement) I'm declaring an Iterator object on personList (any class that extends the Collection class can invoke the .iterator() method). An Iterator holds all the values of a collection and gives you tools for moving through and manipulating the list (Note: you can only move forward). I am then setting up the condition for when the for loop should run, in this case when my Iterator object returns false after the last member of my list the program will drop out of the loop. Usually there would be a next statement in a for loop declaration, however it is optional and typically isn't necessary in a foreach loop.
Inside the loop we are assigning a person object to the current iter element, which is of course based on our list we declared earlier. Because an Iterator doesn't know what it holds you must cast the object type when you retrieve it from the Iterator (this issue is solved in 1.5 with parameterization). Next we have have an if statement checking for the name “Joe” in the firstName attribute of a person object, if true the “iter.remove()” method is called. This is a handy method which removes the current element from the Iterator object and also from the underlying list. So if I was to attempt to iterate through the personList again, all person objects with the firstName of “Joe” will have been removed. If you haven't already been exposed to it, the continue statement ends the current iteration of the loop. It's not really necessary here, but I added as it's a common practice.
That's all nice but why?
I choose to use the for loop method for imitating a foreach loop because; it keeps the code clean by putting all the loop declaration stuff into one place and the Iterator object is dropped from memory at the same time the for loop goes out of scope. The other way of handling a for each loop in pre-1.5 Java would be the following:
Iterator iter = personList.iterator();
while(iter.hasNext()){
Person person = (Person)iter.next();
if(person.getFirstName().equals("Joe")){
iter.remove();
continue;
} else if(person.getFirstName().equals("Cindy")){
System.out.println(person.getFirstName() + " wins again!");
}
System.out.println(person.getFirstName());
}
//Prints "Cindy wins again!"
To me the code doesn't look as clean and the program holds on to the Iterator object even though it is no longer useful (remember you cannot re-iterate through an Iterator object). It's a matter of preference, but using the for loop method will always be the better choice from a strictly programmatic perspective.
Related posts:
