Page 1 of 1

Beginning With For Each Loops Rate Topic: -----

#1 Viske  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 24
  • View blog
  • Posts: 70
  • Joined: 07-June 11

Posted 20 September 2011 - 02:58 AM

*
POPULAR

This tutorial will focus on how to use the for each loop in Java. We will cover the basic implementation and cover how to allow our own data structures to use for each. Let's get on with it!

What is a For Each loop?

A For Each loop is a way of iterating over a collection or data structure. The benefit of using the For Each loop instead of your typical For loop is that we have access to the objects in the collection.

A for each loop is declared as
	for (type variable : collection) { statements; }



As you can see, we don't need to increase a counter each time we go through the loop, nor do we need to check that the index is in range. This is all done for us. A quick example:

	// Array with 5 elements, 1-5
	int[] array = {1, 2, 3, 4, 5};
	 
	// Print each element in the array to console
	for (int i : array) {
	    System.out.println(i);
	}



This would output:

1
2
3
4
5

Now, this doesn't seem like a massive thing - and it's not, really. It does makes things easier to do though. Now, we can also use the for each loop to iterate over other collections, such as HashMaps. This is slightly more complicated.

Editing Elements
One of the limitations of the For Each loop is that you are unable to edit elements within a Collection. An example to demonstrate this:

import java.util.ArrayList;

public class Main {

    public static void main(String[] args) {
        // Create a new ArrayList and add some elements to it
        ArrayList<String> names = new ArrayList<String>();		
        names.add("Steve");
        names.add("Joe");
        names.add("Bob");

        // Go through and change each String s in names, then print to console
        for (String s : names) {
            s += " After Edited";
            System.out.println(s);
        }
		
        // Print each String s in names to console
        for (String s : names) {
            System.out.println(s);
        }
    }
}


Now you may expect the above code to output the same in each foreach loop. The actual output is:

Steve After Edited
Joe After Edited
Bob After Edited
Steve
Joe
Bob

Changing the variable in the foreach loop will not change it in the collection. It is a copy, and so anything you do with it will not be edited outside of the loop. So we can edit the variable, although maybe not with the results that we'd expect. What about editing the collection? Let's try replacing

for (String s : names) {
    s += " After Edited";
    System.out.println(s);
}



with

for (String s : names) {
    names.remove(s);
    System.out.println(s);
}



Now, think about what would happen if this were legal. We would remove String s from names, but String s is actually a copy - so we can still access it and edit it as we wish. Obviously, this could lead to some unintended and possibly surprising behaviour. So this will throw an exception - specifically, a ConcurrentModificationException. The output:

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
at java.util.AbstractList$Itr.next(Unknown Source)
at Main.main(Main.java:12)

It's telling you that you can't modify the collection while it is already being accessed. If you would like to edit the elements a collection has, you can use an Iterator to do so:

import java.util.ArrayList;
import java.util.Iterator;

public class Main {

    public static void main(String[] args) {
    // Create an ArrayList and add some elements
        ArrayList<String> names = new ArrayList<String>();		
	names.add("Steve");
	names.add("Joe");
	names.add("Bob");
		
        // Create an Iterator. Notice that we instantiate by called iterator() on the collection
	Iterator<String> iter = names.iterator();
		
        // Remove each elemenet in the collection. Notice that we use iterator.remove.
	while (iter.hasNext()) {
	    iter.next();    // Get the next element. Will throw IllegalStateException otherwise
	    iter.remove();
	}
		
        // Print the ArrayList to the console
	System.out.println(names);
    }
}


The output will be:

[]

HashMaps and For Each Loops
	// Map.Entry is what we will be using to iterate over the HashMap
	import java.util.Map.Entry;
	import java.util.HashMap;
	 
	public class Main {
	    // Declaring our HashMap - we have to use Integer instead of int here. Same as
	    // Double, Float, etc.
	    // String - name, Integer - age
	    private static HashMap<String, Integer> people;
	 
	    public static void main(String[] args) {
	        // Instantiate our HashMap and add some entries.
	        people = new HashMap<String, Integer>();
	        people.put("John Doe", 35);
	        people.put("Jane Doe", 27);
	        people.put("Bobby", 24);
	 
	        // Go through and print the Name and Age of each person.
	        for (Entry<String, Integer> entry : people.entrySet()) {
	            System.out.println("Name: " + entry.getKey());
	            System.out.println("Age: " + entry.getValue());
	        }
	    }
	}



Now, to explain the for each loop.

	for (Entry<String, Integer> entry : people.entrySet()) {



Quite a lot is happening here. First, Entry<String, Integer> entry is creating a Map Entry variable - entry. A Map Entry is a way of accessing elements from an Entry Set, and will hold a Key and Value.

Next, we get use people.entrySet() to get a Set of the collection. We use this to iterate over. Anything that we do with the entry set also happens to the HashMap, so if we remove an element, it is removed from both.

	System.out.println("Name: " + entry.getKey());
	System.out.println("Age: " + entry.getValue());



Here we access the Key and Value of the entry - fairly straight forward.

The output of the above code. Notice how it isn't sorted, or in the order you put them in due to how HashMaps work.

Name: John Doe
Age: 35
Name: Bobby
Age: 24
Name: Jane Doe
Age: 27

Implementing For Each for Our Own Classes

	import java.util.Iterator;
	 
	// Create a new collection that implements Iterable
	public class NewCollection<E> implements Iterable<E> {
	    public Iterator<E> iterator() {
	        // Implement code to iterate collection here
	        // Outside the scope of this tutorial
	    }
	}
	 
	public class Main {
	    public static void main(String[] args) {
	        // Create an instance of our new collection
	        MyCollection<String> collection = new MyCollection<String>();
	 
	        // Code to insert stuff in our collection
	 
	        // Using For Each loop with our collection. Easy!
	        for (String s : collection) {
	            System.out.println(s);
	        }
	    }
	}



It's relatively simple to allow the use of For Each on our own collections - we just have to implement Iterable.

And that's For Each loops!

Is This A Good Question/Topic? 6
  • +

Page 1 of 1