First Time Heuristic

I’ve been thinking, a bit, about this algorithm. Imagine that you want to write out a comma-separated list of items. Back in the old, old days of Java 1.4, I’d probably write something like this:

List items = getItems();
for (int i = 0, length = items.size(); i < length; i++) {
  if (i > 0) {
    writer.write(",");
  }
  writer.write((String) items.get(i));
}

What we expect this to produce is something like this:


one,two,three,four

That’s okay, if a bit meh. The part of it that always gets me thinking is the little conditional check. I only want commas in-between the items, which means that I only want to write after the first iteration.

Since the days of Java 5, I’ve found myself writing this:

boolean firstTime = true;
for (String item : getItems()) {
  if (!firstTime) {
    writer.write(",");
  }
  writer.write(item);
  firstTime = false;
}

This does the same thing. But, speaking for myself, I really hate the structure. First because it leaves a dangling variable, first that hangs around after its usefulness. And second, because it’s far too easy to forget to toggle the flag at the end of the for loop. And yet, it’s what I find myself writing again and again. Enough times that I’m finding it kinda ugly.

I suppose I could do something like this:

StringBuilder builder = new StringBuilder();
for (String item : getItems()) {
  if (builder.length() > 0) {
    builder.append(",");
  }
  builder.append(item);
}
writer.write(builder.toString());

But that doesn’t feel, to me, like it make my life too much easier: I mean, I still have that dangling variable, except that now it’s a StringBuilder instead of a boolean flag. And there’s a good chance of error, if one of the Strings in the list is the empty String.

And perhaps I should just go back to the original for semantics, and use an iterator variable, i, which I can interrogate to figure out first-time-ness.

I suppose, really, what I want is some kind of smarter iterator. Like this:

for (Iteration<String> iteration : asIteration(getItems())) {
  if (!iteration.isFirstTime()) {
    writer.write(",");
  }
  writer.write(iteration.getValue());
}

That’s actually an easy utility to build, and it’s fairly general-purpose. You could even have the Iteration class expose an index number for those instances where you want to spit out a line number.

Now, arguably, without the index number, the above is semantically equivalent to:

for (Iterator<String> i = getItems().iterator(); i.hasNext(); ) {
  writer.write(i.getNext());
  if (i.hasNext()) {
    writer.write(",");
  }
}

You lose the benefit of the more simplified for structure, but it accomplishes the same end, with maximum simplicity. But, like I say, the idea of something that can tell me its line number is kind of attractive. And I hate to count the number of times I’ve forgotten to call the hasNext() method.

Or maybe I just think about little things like this too much.

It's only fair to share...
Share on FacebookGoogle+Tweet about this on TwitterShare on LinkedIn

Leave a Reply