FinderTemplate

Ryan Sonnek bio photo By Ryan Sonnek

I think I’m becoming addicted to Ruby syntax. The Ruby collection API is super slick, and since I’ve already brought a Ruby-like iteration syntax to Java, I think it’s logical to try and port the Ruby find syntax to Java as well.

My goal is to create a simple client API for looping through a collection, looking for a certain object. Here’s how I want it to work.

MyObject foundObject = (MyObject) new FinderTemplate(entries) {
  protected boolean isMatch(Object object) {
    MyObject entry = (MyObject) object;

    //perform any required matching logic

    return true;
  }
}.find();

The code for the FinderTemplate is very similar to my previous IteratorTemplate. Nothing too fancy, but it’s pretty slick.

public abstract class FinderTemplate {
  private final Collection objects;

  public FinderTemplate(Collection objects) {
    this.objects = objects;
  }

  public Object find() {
    for (Iterator iter = objects.iterator(); iter.hasNext();) {
      Object element = (Object) iter.next();
      if (isMatch(element)) {
        return element;
      }
    }
    return null;
  }

  protected abstract boolean isMatch(Object object);
}

What I think is very cool is how this FinderTemplate can be extended ever so slightly to add a findAll method. So, instead of just finding one_object, you can find _all objects that meet your criteria.

Here’s the only change needed to the FinderTemplate to add this new behaviour.

public Collection findAll() {
  Collection results = new ArrayList();
  for (Iterator iter = objects.iterator(); iter.hasNext();) {
    Object element = (Object) iter.next();
    if (isMatch(element)) {
      results.add(element);
    }
  }
  return results;
}

I think it would be great if this code could find a home somewhere like commons-collections. I’m not sure if there’s much interest for this code though, unless you’ve been exposed to Ruby.