import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Predicate; import java.util.function.UnaryOperator; import java.util.stream.Stream; public interface TailRecursive { public static Function new_(Function toIntermediary, UnaryOperator unaryOperator, Predicate predicate, Function toOutput) { return input -> $.new_( Stream.iterate( toIntermediary.apply(input), unaryOperator ), predicate, toOutput ) ; } public static BiFunction new_(BiFunction toIntermediary, UnaryOperator unaryOperator, Predicate predicate, Function toOutput) { return (input1, input2) -> $.new_( Stream.iterate( toIntermediary.apply(input1, input2), unaryOperator ), predicate, toOutput ) ; } public enum $ { $$; private static OUTPUT new_(Stream stream, Predicate predicate, Function function) { return stream .filter(predicate) .map(function) .findAny() .orElseThrow(RuntimeException::new) ; } } }