Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

A Monoflop class for easier looping...

DZone's Guide to

A Monoflop class for easier looping...

· Java Zone ·
Free Resource

Bring content to any platform with the open-source BloomReach CMS. Try for free.

Whether you want to join the contents of a collection or build a URL query string, there are a lot of cases where you have to handle the first iteration of a loop a bit differently from all others. I often used this construct:

List<String> listToJoin = ...
boolean first = true;
StringBuilder result = new StringBuilder();
for(String item : listToJoin) {
   if (!first) {
      result.append(", ");
   }
   first = false;
   result.append(item);
}

System.out.println(result);
Yes, this works like a charm, but it also looks plain ugly. And don't ask how long you have to debug if you get the position of the first = false wrong.

A simple class called Monoflop can help here. A properly commented version can be found on GitHub, but a very short version will do here.  Using this neat helper results in the following:

public class Monoflop {

    private boolean toggled = false;

    /**
     * Reads and returns the internal state.
     * Toggles it to true once.
     */
    public boolean successiveCall() {
        if (toggled) {
            return true;
        }
        toggled = true;
        return false;
    }
    /**
     * Inverse of successiveCall
     */   
    public boolean firstCall() {
        return !successiveCall();
    }
}

And this...

List<String> listToJoin = ...
Monoflop mf = new Monoflop();
StringBuilder result = new StringBuilder();
for(String item : listToJoin) {
   if (mf.successiveCall()) {
      result.append(", ");
   }
   result.append(item);
}

System.out.println(result);

Granted, you didn't save a whole lot of lines in this example. However, the logic is much more visible, and you have less possibilities for errors. The only thing that is a bit misleading is the call named successiveCall(), which has side-effects. On the other hadn, as it toggles the internal state, I didn't want to make it a getter ( isSuccessiveCall()) since that would be even more evil.

Feel free to use this class in your own code base (but use the one from GitHub - as it is better documented). However, if you like it and you have uses for the fastest dependency injection framework out there with lots of other features, check out: SIRIUS ( GitHub), which contains Monoflop.  It is OpenSource (MIT license) and developed and maintained by scireum GmbH.

BloomReach CMS: the API-first CMS of the future. Open-source & enterprise-grade. - As a Java developer, you will feel at home using Maven builds and your favorite IDE (e.g. Eclipse or IntelliJ) and continuous integration server (e.g. Jenkins). Manage your Java objects using Spring Framework, write your templates in JSP or Freemarker. Try for free.

Topics:

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}