You need to perform logic that is predicated on a certain condition being satisfied, and you want to encapsulate this condition in an object.
Use a Predicate
to evaluate a criteria or a
condition. A Predicate
is an object that evaluates
another object and returns true
or
false
; predicates are used throughout the Commons
Collections packages for filtering, selecting, and validating the
contents of collections. This code demonstrates the use of simple
predicates to test the type and contents of an object:
import org.apache.commons.collection.Predicate; import org.apache.commons.collection.functors.*; String name = "Tim"; Predicate nameJohn = new EqualPredicate( "John" ); Predicate nameTim = new EqualPredicate( "Tim" ); Predicate instanceString = new InstanceofPredicate( String.class ); Predicate instanceDouble = new InstanceofPredicate( Double.class ); // Testing all predicates for "Tim" System.out.println( "Is Name John?: " + nameJohn.evaluate( name ) ); System.out.println( "Is Name Tim?: " + nameTim.evaluate( name ) ); System.out.println( "Is this a String?: " + instanceString.evaluate( name ) ); System.out.println( "Is this a Double?: " + instanceDouble.evaluate( name ) );
The previous example tests the name
object against
a few Predicate
implementations producing the
following console output:
Is Name John?: false Is Name Tim?: true Is this a String?: true Is this a Double?: false
The string “Tim” is subjected to
various Predicate
tests. The first two
EqualPredicate
objects test the contents of the
string, returning true
if the object being
evaluated is equal to the object passed into the
EqualPredicate
’s constructor. The
last two Predicate
objects are
InstanceofPredicate
instances, which test the type
of object being evaluated; if an
InstanceofPredicate
constructor is passed to the
String
class, it returns true
if the object being evaluated is a
java.lang.String
type.
The simple Predicate
interface is central to a
number of utilities introduced in this chapter. To implement
Predicate
, define an evaluate()
method that returns a boolean
; a
Predicate
is a function object (or functor) that
captures a criteria in an object that can be created and altered at
runtime. Creating and evaluating a Predicate
is
just as valid as writing an if
statement; for
example, the code in the Solution of this recipe could have been
implemented as a series of if
statements:
String name = "Tim"; if( name.equals( "John" ) ) { System.out.println( "The name is John." ); } if( name.equals( "Tim" ) ) { System.out.println( "The name is Tim." ); } if( name instanceof String ) ) { System.out.println( "name is as String object" ); } if( name instanceof Double ) ) { System.out.println( "name is as Double object" ); }
Predicate
instances capture an
if
statement in an object, and if you are going to
constantly change the behavior of your application, you might want to
consider placing conditional expressions in
Predicate
instances. For example, if a system is
designed to classify a storm as being a hurricane, you may want to
capture all of your classification criteria in an XML
file—parsing this file at runtime and creating a series of
Predicate
objects. A storm is a hurricane when the
winds exceed a certain value, and the barometric pressure falls below
a certain point. But, in a few years those criteria might change to
involve a new, or more complex, set of measurements. If your decision
logic is encapsulated in a Predicate
object, it
will be easier to upgrade the program to take new criteria into
account; all of this logic will be encapsulated in an instance of
Predicate
.
Commons Collections provides a number of basic predicates for common
situations, such as testing to see if an object equals another object
(EqualPredicate
), or that an object is of a
certain type (InstanceofPredicate
). Table 4-1 lists a number of simple
Predicate
implementations.
Table 4-1. Predicate implementations
Name |
Description |
---|---|
|
Compares each object to an object passed via a constructor—returning true if the two are equal. |
|
Returns true if the object being evaluated is the same object
reference as the object passed to its constructor. The
|
|
Wraps a |
|
Returns |
|
Returns true if the object being evaluated is |
|
Returns true if the object being evaluated is not
|
|
Always returns |
|
Always returns |
|
Returns |
The following example demonstrates
simple
Predicate
objects with a test for equality,
inequality, and equality by identity:
import org.apache.commons.collections.Predicate; import org.apache.commons.collections.functors.*; ... String testName = "Ben"; Predicate equals = new EqualPredicate( testName ); Predicate notEquals = new NotPredicate( equals ); Predicate identity = new IdentityPredicate( testName ); System.out.println( "Does name equal 'Ben'? " + equals.evaluate( "Ben" ) ); System.out.println( "Is object 'Ben'? " + identity.evaluate( testName ) ); System.out.println( "Does name equal 'Tim'? " + equals.evaluate( "Tim" ) ); System.out.println( "Does name not equal 'Tim'? " + notEquals. evaluate( "Tim" ) ); System.out.println( "Is object 'Tim'? " + identity.evaluate( "Tim" ) );
This code demonstrates the use of Predicate
objects to determine if objects are equal or if two object references
reference the same instance. When executed, the following is output
to the console:
Does name equal 'Ben'? true Is object 'Ben'? true Does name equal 'Tim'? false Does name not equal 'Tim'? true Is object 'Tim'? false
The following code demonstrates simple predicates that test for the
presence or absence of null
or if an object being
evaluated is of a certain type. The example also demonstrates the use
of a UniquePredicate
that returns true
when it encounters an object for the first time:
import org.apache.commons.collections.Predicate; import org.apache.commons.collections.functors.*; String nullString = null; Double testDouble = new Double(3.4); Predicate isString = new InstanceofPredicate( String.class ); Predicate isLong = new InstanceofPredicate( Long.class ); Predicate isNumber = new InstanceofPredicate( Number.class ); Predicate isNotNull = NotNullPredicate.INSTANCE; Predicate isNull = NullPredicate.INSTANCE; Predicate unique = new UniquePredicate( ); System.out.println("'nullString' not null?: " + isNotNull. evaluate(nullString)); System.out.println("'nullString' null?: " + isNull.evaluate(nullString)); System.out.println("'testDouble' a String?: " + isString. evaluate(testDouble)); System.out.println("'testDouble' a Long?: " + isLong.evaluate(testDouble)); System.out.println("'testDouble' a Number?: " + isNumber. evaluate(testDouble)); System.out.println("'A' Unique?: " + unique.evaluate("A")); System.out.println("'C' Unique?: " + unique.evaluate("C")); System.out.println("'A' Unique?: " + unique.evaluate("A")); System.out.println("'B' Unique?: " + unique.evaluate("B"));
The sample evaluates objects against the
InstanceofPredicate
, the
NullPredicate
, the
NotNullPredicate
, and the
UniquePredicate
, and the following is output to
the console:
'nullString' not null?: false 'nullString' null?: true 'testDouble' a String?: false 'testDouble' a Long?: false 'testDouble' a Number?: true 'A' Unique?: true 'C' Unique?: true 'A' Unique?: false 'B' Unique?: true
The UniquePredicate
returns
false
the second time it encounters
“A.” The Double
object testDouble
is shown to be a
Number
object, and the
nullString
is evaluated as
non-null
.
This recipe mentions function pointers in C and C++. Function pointers are pointers to the address of a function, and they allow for some interesting logical acrobatics. For more information about function pointers in C and C++, see http://www.function-pointer.org/.
Predicate
, Closure
, and
Transformer
are all functor objects that are used
throughout the Commons Collections component. You may be familiar
with functors if you have used the Standard Template Library (STL) in
C++. STL documentation contains rigorous definitions for function
objects and
predicates. For more information
about functors in STL, see http://www.sgi.com/tech/stl/functors.html.
Get Jakarta Commons Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.