FlipFlopPredicate.java
package epam.flipflop;
import java.util.function.Predicate;
import static java.util.Objects.requireNonNull;
/**
* A predicate that emulates flip-flop logic similar to the two-dots flip-flop in Perl or Ruby.
* The predicate takes two input predicates, a start condition, and an end condition.
* When the start condition is met, the predicate returns true for all subsequent inputs
* until the end condition is met, at which point it returns true and resets its internal state.
*
* @param <T> The type of the input to the predicate
*/
public class FlipFlopPredicate<T> implements Predicate<T> {
private final Predicate<? super T> startPredicate;
private final Predicate<? super T> endPredicate;
private boolean state;
/**
* Constructs a new FlipFlopPredicate with the given start and end conditions.
*
* @param startCondition The predicate that represents the start condition
* @param endCondition The predicate that represents the end condition
*/
public FlipFlopPredicate(Predicate<T> startCondition, Predicate<T> endCondition) {
this.startPredicate = requireNonNull(startCondition);
this.endPredicate = requireNonNull(endCondition);
}
/**
* Evaluates this predicate on the given argument.
*
* @param value The input argument
* @return {@code true} if the input matches the flip-flop logic, otherwise {@code false}
*/
@Override
public boolean test(final T value) {
var result = state || startPredicate.test(value);
state = result && !endPredicate.test(value);
return result;
}
}