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

Start coding something amazing with our library of open source Cloud code patterns. Content provided by IBM.

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.

Use this tool to look at the contents of GitHub and classify code based on the programming language used.  Content provided by IBM Developer.

Topics:

Opinions expressed by DZone contributors are their own.

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

{{ parent.tldr }}

{{ parent.urlSource.name }}