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.
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.
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.
A utility class MUST contain only static methods.
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:
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With