Please consider the following two functions:
public static <X, Y, U, V extends X> Function<U, Y> composite(
Function<X, Y> first, Function<U, V> second)
{
Objects.requireNonNull(first);
Objects.requireNonNull(second);
return (U arg) -> first.apply(second.apply(arg));
}
public static <X, Y extends X> Function<X, ?> iterate(Function<X, Y> function, int n)
{
if (n < 0)
return null;
if (n == 0)
return (X arg) -> arg;
Objects.requireNonNull(function);
Function<X, Y> iteration = function;
for (; n > 1; --n)
iteration = composite(function, iteration);
return iteration;
}
While composite(first, second)
computes the composition of first
and second
, iterate(function, n)
computes the nth
iterate of function
.
While the restriction Y extends X
suffices for any n > 0
, we've got some problem with n == 0
. Mathematically, iterate
should yield the identity function. However, therefore we would need X extends Y
, i.e. X == Y
, as well.
Please consider the following example
Function<Double, Double> nthSquareRoot = iterate(Math::sqrt, n);
This yields the error message:
Type mismatch: cannot convert from Function<Double,capture#2-of ?> to Function<Double,Double>
What's the best option here? If n == 1
, we could check if X
is acceptable as Y
. I would like to hear other options and some ideas how this check can be performed (as far as I know, there is no simple solution to check two generic parameters for equality).
Introduced in Java 8, the forEach loop provides programmers with a new, concise and interesting way to iterate over a collection.
By using this iterator object, you can access each element in the collection, one element at a time. Obtain an iterator to the start of the collection by calling the collection's iterator() method. Set up a loop that makes a call to hasNext(). Have the loop iterate as long as hasNext() returns true.
Try:
public static<X> UnaryOperator<X> iterate(UnaryOperator<X> f, int n) { ... }
If Y <: X, then a function from X to Y is also a function from X to X, and you should be able to do what you want.
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