Let's say I have code like this
@FunctionalInterface
interface Callable {
Integer multiply(Integer by);
}
class Builder {
private Integer multiplier;
public Builder multiplyBy(Integer multiplier) {
this.multiplier= multiplier;
return this;
}
public Callable build() {
return (value) -> value * multiplier; //how to "bake" hever value
}
}
// calling
Builder builder;
Callable multiplierBy3 = builder.multiplyBy(3);
Callable multiplierBy6 = builder.multiply(6);
multiplierBy3.multiply(10); //should return 30, returns 60
multiplierBy6.multiply(10); // return 60, ok, propably because of new multipier value
Behavior happens because calling second time multiplyBy sets new value in builder.
How I can manage to create each lambda own multiplier function?
Like @Kayaman said:
Use two builders, that's where you're keeping the lambda state.
So the solution will be this way:
Builder builderBy3 = new Builder();
Builder builderBy6 = new Builder();
Callable multiplierBy3 = builderBy3.multiplyBy(3).build();
Callable multiplierBy6 = builderBy6.multiplyBy(6).build();
System.out.println(multiplierBy3.multiply(10)); // Returns 30
System.out.println(multiplierBy6.multiply(10)); // Returns 60
But you can also do it modifying the Builder:
class Builder {
private Integer multiplier;
public Builder multiplyBy(Integer multiplier) {
this.multiplier = multiplier;
return this;
}
public Callable build() {
int currentMultiplier = this.multiplier; // Current multiplier value
return (value) -> value * currentMultiplier; // Use it in the lambda
}
}
Then you can do:
Builder builder = new Builder();
Callable multiplierBy3 = builder.multiplyBy(3).build();
Callable multiplierBy6 = builder.multiplyBy(6).build();
System.out.println(multiplierBy3.multiply(10)); // Returns 30
System.out.println(multiplierBy6.multiply(10)); // Returns 60
It's called a closure. When a value goes out of scope, the lambda still retains access to it. Using Functional interfaces or methods to convert f(x,y) to f(x)(y) is known as currying. Note that you can use existing interfaces.
Function<Integer, UnaryOperator<Integer>>
createMultiplier = (operand1 -> operand2 -> operand1
* operand2);
Function<Integer, Integer> multiplyBy3 = createMultiplier.apply(3);
Function<Integer, Integer> multiplyBy6 = createMultiplier.apply(6);
int result1 = multiplyBy3.apply(10);
int result2 = multiplyBy6.apply(20);
System.out.println(result1);
System.out.println(result2);
prints
30
120
Here is one I created some time ago for my own use. It allows the creation of a log function for any base. I created an interface to give more appropriate names to the methods.
interface Log {
double of(double value);
static Log forBase(double base) {
// compute logBase once for given base
final double logBase = Math.log(base);
return value -> Math.log(value) / logBase;
}
}
Log log2 = Log.forBase(2);
System.out.println(log2.of(32));
Or if you just need to get the log once.
System.out.println(Log.forBase(2).of(32));
Both print
5.0
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