Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Predicates in Utils class should be provided as constants or as static method?

Lately, I have been working with predicates and guava utilities. I have created a Utils.class where I store some predicates that I use in different parts of the code. Thus this issue has come up and we (me and my workmates) do not get an agreement about it.

What is the right way or "good practice way" to put a predicate in a utility class?, as a constant defining it with capital letter or in a static method?. Following, I write an example:

public final class Utils {

public static final Predicate<Element> IS_SPECIAL = new Predicate<Element>() {
    @Override
    public boolean apply(Element elem) {
        return elem.special;
    }
};


public static Predicate<Element> isSpecial() {
    return new Predicate<Element>() {
        @Override
        public boolean apply(Element elem) {
        return elem.special;
    }}

By the way, guava offers some predifining predicates and it provides them as a method that returns predicates, but other libreries do the same offering them as constants.

like image 982
Maria Montenegro Avatar asked Feb 03 '16 12:02

Maria Montenegro


People also ask

Should util classes have static methods?

Pure utility classes should usually be static. When you have a class with well-defined input and output, no side effects and no state, then by definition it should be a static class.

Why util methods are static?

Static methods are utility methods defined in a class that do not fit the tradition method- receiver pattern. Static methods are used where there is not a natural choice of a receiver object for the problem the method solves.

Should utility methods be static Java?

A utility class MUST contain only static methods.


1 Answers

There are two views to this: the API and the implementation.

About the API, the solution using a method is much more flexible than the others. It allows to change the implementation without caring about the code, meaning that your code is not impacted by any change you'll do hidden behind the method.

About the implementation, people usually use an enumeration. The advantage of the enumeration over a constant here are numerous:

  1. It's thread-safe. If you use a singleton variable, you can still have issues with the memory if some things are badly handled. An enumeration is part of the language and the definition will force every enum constant to be loaded consistently.
  2. As rinde mentions in the comments, an enum is serializable. That means that you can persist your predicates for further reference.
  3. An enumeration provides a kind of sub-namespace. If you want to create several predicates, they can all be defined in the same place, making it easy to find them all.
  4. Enumerations don't pollute the code with explicit subclasses and you will not see new Predicate<Element> every few lines. However the nature of such enums make it impossible to have the same in the compiled classes. So here, it's purely better on the source code level. Of course, that's what you want, since you actually write source code.

Here's an example of how I would do it. (Yes, I'd even rename Utils to Elements, following the recent Java tacit conventions).

public final class Elements {
  private static enum ElementPredicate implements Predicate<Element> {
    SPECIAL {
      @Override public boolean apply(Element e) { return e.special; }
    }
  }

  public static Predicate<Element> isSpecial() {
    return ElementPredicate.SPECIAL;
  }

  private Elements() {}
}

Finally, note that if you're using Java 8, you should stick to the lambda mechanism offered, as Louis Wasserman mentioned in the question comments. But since the lambas are not usable in your example, because you're not retrieving special from a method but from the field directly, this advice is, unfortunately, void. However if you had a isSpecial() method on Element, you could then write your predicates directly in your code, like this:

Stream<T> stream = ... ;
stream
    .filter(Element::isSpecial)
like image 148
Olivier Grégoire Avatar answered Sep 22 '22 10:09

Olivier Grégoire