Using Intunaryoperator Java Interface to return n functions

Asked

Viewed 40 times

1

I am reading the documentation of this bookstore that is in the title.

I want to implement a method that returns a composition of functions, if I not by arguments must return the identity function, if 1 must return only the function, if n>1 must return to all functions, as the example:

1 IntUnaryOperator[] functions = {
2 compose(),
3 compose(x -> x+1),
4 compose(x -> x*2, x -> x+1),
5 compose(x -> x+1, x -> x*2),
6 compose(x -> x+1, x -> x*2, x -> x+1)
7 };
8 for (IntUnaryOperator f : functions) System.out.println(f.applyAsInt(1));
9 // Resultado esperado: 1, 2, 3, 4, 5

I imagine I should start like this, but I don’t know how to use both functions consistently yet, I need an intuition of how to proceed.

import java.util.function.IntUnaryOperator;

public class IntOperatorsUtil {

  public static IntUnaryOperator compose(IntUnaryOperator... functions) { 

2 answers

1

I was able to get what I wanted, if it’s useful to anyone in the future:

  public static IntUnaryOperator compose(IntUnaryOperator... functions) {
    IntUnaryOperator toReturn = x -> x;
    for (IntUnaryOperator f : functions) {   
         toReturn = toReturn.compose(f);
    };
    return toReturn;
  }

1


An alternative to your solution is to create a stream with the functions and use the method Stream::reduce to return a composition of all functions:

public static IntUnaryOperator compose(IntUnaryOperator... functions) {
    return Arrays.stream(functions).reduce(IntUnaryOperator.identity(), IntUnaryOperator::compose);
}

Note also that I used the method IntUnaryOperator::identity, which already returns the identity function (it is okay that it is trivial to create another, but if you already have something ready, why not use?)

The reduce above is equivalent at the loop that you made: the initial value is the identity function, and it goes calling the method compose with the other functions.


Another option - semantically equivalent - is:

public static IntUnaryOperator compose(IntUnaryOperator... functions) {
    return Arrays.stream(functions).reduce(IntUnaryOperator::compose)
        .orElse(IntUnaryOperator.identity());
}

In this case, the reduce returns a Optional. In it we use the method orElse to return the identity function if there are no functions to be composed.


Remembering that streams have their cost and in general will be slower than a loop traditional. You should balance the speed (if indeed a problem) versus the clarity/concision of the code and other benefits than the streams can bring (of course). Maybe for small programs it doesn’t make much difference, but for larger systems it’s something to consider.

  • 1

    thank you very much, I got interested in the solution and I will study about stream

Browser other questions tagged

You are not signed in. Login or sign up in order to post.