Use a WhileClosure, passing in
a Predicate and a Closure. The WhileClosure will execute the Closure as long as a Predicate evaluates to true. The following example demonstrates a
Closure named drive, which operates on a Car object and a Predicate named hasFuel, which evaluates the Car object. Each time a Car is passed to drive, a gallon of fuel is used, and hasFuel will evaluate to true if the amount of fuel in a car is greater
than zero. The WhileClosure, useAllFuel, evaluates drive until hasFuel evaluates to false:
import org.apache.commons.collections.Closure;
import org.apache.commons.collections.Predicate;
import org.apache.commons.collections.functors.WhileClosure;
Closure drive = new Closure( ) {
public void execute(Object input) {
Car car = (Car) input;
car.setFuel( car.getFuel( ) - 1 );
}
}
Predicate hasFuel = new Predicate( ) {
public boolean evaluate(Object object) {
Car car = (Car) input;
return car.getFuel( ) > 0;
}
}
Closure useAllFuel = new WhileFuel( hasFuel, drive );
Car car = new Car( );
car.setMakeModel( "Ford Escort" );
car.setFuel( 20 );
System.out.println( "Car before while closure: " + car );
useAllFuel.execute( car );
System.out.println( "Car after while closure: " + car );The WhileClosure, useAllFuel, takes a Car object, executing a Closure and evaluating a Predicate after every execution. The state of
the car is printed both before and after it is passed to the WhileClosure:
Car before while closure: Ford Escort with 20 gallons of fuel. Car after while closure: Ford Escort with no fuel.
If you need to execute a Closure a set number of times, you can also
use a ForClosure, passing in an
int that specifies the number of
times an object is passed to the execute(
) method of a Closure. This
example uses the same Closure defined
in the Solution, but, this time, the drive Closure is only executed five times:
Closure driveSome = new ForClosure( 5, drive ); Car car = new Car( ); car.setMakeModel( "Toyota Camry" ); car.setFuel( 20 ); System.out.println( "Car before for closure: " + car ); driveSome.execute( car ); System.out.println( "Car after for closure: " + car );
Since the driveSome Closure is called only five times, the Camry
still has 15 gallons after the ForClosure is executed:
Car before for closure: Toyota Camry with 20 gallons of fuel. Car after for closure: Toyota Camry with 15 gallons of fuel.
