Java for .net-guys or foreach in Java

Tags:
3 Comments »

Disclaimer: I’m absolutely not the person who can tell a lot about Java. I learned it a few years ago for university, but used it most of the time only for small example stuff. Never as deep as I’m working with .net. But maybe my newest discoveries are useful for more programmers with .net background.

I started using Java 1.4 and until last week I never took a look at Java 5 or 6. The only thing I was aware of were generics in Java.

iterators in Java

I was always annoyed in the missing of a foreach loop in Java. There is a concept of iterators in Java comparable to the .net Enumerators. But to loop over a list you will find in millions of Java programs the following code:

Iterator<Integer> i = list.iterator();
while(i.hasNext()) {
    Integer current = i.next();

    // do something with the current element
}

Sometimes build into a regular for loop, but I don’t think that is more readable or convenient:

for(Iterator<Integer> i = list.iterator(); i.hasNext(); ) {
    Integer current = i.next();

    // just do something
}

By the way: Can anyone tell me why the method is called iterator() and not getIterator() as used everywhere else in Java?

foreach in Java

With Java 5 (or 1.5 – call it as you like) a foreach loop was introduced. This is about five years ago, so I’m very fast in getting news from the Java world.

for(Integer i : list) {
    // just use i as the current element
}

I like it. It’s working for everything that implements java.lang.Iterable and for regular arrays.

Access to modified closure

Tags: , ,
No Comments »

Imaging a small C# winform app with just one ListBox and the following code:

private void Form1_Load(object sender, EventArgs e)
{
    for (int i = 0; i < 5; i++)
    {
        Thread t = new Thread(() => AddToListbox(i));
        t.Start();
    }
}

private void AddToListbox(int i)
{
    if (this.InvokeRequired)
        this.Invoke(new Action<int>(AddToListbox), i);
    else
        this.listBox1.Items.Add(i);
}

A simple loop iterating over the numbers from 0 to 4 and adding these values asynchronous to a ListBox. What do you expect? I expected the numbers from 0 to 4 shown in the ListBox but in any random order since I do not control the threads in any way.

2 - 3 - 4 - 5 - 5 4 - 2 -  2 - 4 - 5

I didn’t expect any number to appear multiple times and I’m totally surprised to  see the number 5!

But ReSharper gave me a hint that I often saw but never understood:

"Access to modified closure" by  R#

So what’s going on?

I use the syntax of an Lambda expression instead of a regular function call (e.g. using the ThreadStart class and a delegate). This Lambda expression is not evaluated until the thread uses it. And by this time, the loop can be in its next iteration. If the loop is already finished i will be 5.

That is exactly what R# tries to tell me: “Hey, you are accessing here a variable but change it later on. Maybe that is not a good idea.”. – It isn’t.

The solution

Just make a copy of i before passing it into the expression. This copy must be a private copy that will not be changed later. The easiest way to do so is declaring a variable inside the body of the loop. In every iteration of the loop a new integer will be created on the stack and the Lambda expression will access this one.

for (int i = 0; i < 5; i++)
{
    int copy = i;
    Thread t = new Thread(() => AddToListbox(copy));
    t.Start();
}
WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Log in