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

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

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.

Download Modern Java EE Design Patterns: Building Scalable Architecture for Sustainable Enterprise Development.  Brought to you in partnership with Red Hat

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 }}