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

The single app analytics solutions to take your web and mobile apps to the next level.  Try today!  Brought to you in partnership with CA Technologies

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.

CA App Experience Analytics, a whole new level of visibility. Learn more. Brought to you in partnership with CA Technologies.

Topics:

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

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

{{ parent.tldr }}

{{ parent.urlSource.name }}