Apr 01

In my project, Xml2Java, I had need for a code that checks reflection information, specifically methods and fields, and operates on relevant ones. For example, I wanted the code that analyses the elements and attributes of a complex element to work only on getter methods, that is, methods that begin with “get” or “is” and return a boolean.

At first, the code looked like this:

for (Method method : clazz.getMethods()) {
  if (method.getName().startsWith("get") ||
    (method.getName().startsWith("is") &&
      method.getReturnType().equals(Boolean.TYPE))) {
    // do stuff
  }
}

It already looks ugly, but the problem really started when I discovered I had other places in my code which needed to work on collections of data in a conditional way. Before thinking too much and searching the web (and if I had, I would have found Apache’s Common Collections) I wrote a simple utility class which offers static methods for decorating an Iterable class, making it yield only results that answer a specific predicate.

So now, after pre-creating predicates like these:

Predicate<Method> isBooleanGetter =
  new Predicate<Method>(Method method) {
    return method.getName().startsWith("is") &&
      method.getReturnType().equals(Boolean.TYPE);
  }

Predicate<Method> isRegularGetter =
  new Predicate<Method>(Method method) {
    return method.getName().startsWith("get");
  }

Predicate<Method> isGetter =
  new OrPredicate<Method>(
    isRegularGetter, isBooleanGetter);

My code looks simple and clean:

for (Method method :
  PredicateIterable.decorate(clazz.getMethods(), isGetter)) {
    // do stuff
}

Simpler, cleaner, and the conditions are encapsulated into small pieces of conditional instances that can be reused and recombined later in other portions of the code. Also, in retrospect regarding Common Collections, they haven’t switched to generics yet which makes my code type-safer, even if not as complete as theirs.

Related Posts with Thumbnails
Share

5 Responses to “Predicated Collections”

  1. Mikael Gueck Says:

    Check out JGA before you roll your own.

  2. Avah Says:

    As I said, I didn’t have much of a look on other frameworks. JGA looks nice – I’ll give it a closer look soon!

    Thanks!

  3. Paul Murray Says:

    Or you can just use java.beans.Introspector, if that’s what you want to do.

    What a pity, btw, that they have not yet replaced BeanInfo with a thoughtful set of annotations.

  4. Daniel Pitts Says:

    I realize this is an old article, but I thought it useful to mention that JavaBean property getters don’t have to start with “is” or “get”. The JavaBean spec allows any named method to be a getter/setter, as long as it’s specified in the BeanInfo class. Its unfortunate that the common misconception that JavaBeans are merely a naming convention has been propagated, and a lot of the useful ideas from the JavaBean spec having been ignored or forgotten.

  5. Avah Says:

    Daniel: What you say is true, it isn’t a necessity and it is a shame that people remember only some conventions instead of the whole idea and specification.

    Hopefully they’ll combine the features listed in the original JavaBeans spec into the final, new properties spec for Java.