Reputation: 2561
I am learning usage of,
java.util.function.Function
I wrote a code which uses java Function to add 4 to itself,
the code is as follows,
public class Test01 {
public static void main(String[] args) {
Function<Integer,Integer> addFunction = new Function<Integer,Integer>() {
private int total = 0;
public Integer apply(Integer value) {
this.total += value;
return this.total;
}
};
int finalTotal = addFunction.andThen(addFunction)
.andThen(addFunction)
.andThen(addFunction)
.apply(4);
System.out.println(finalTotal);
}
}
When I run the above code the output which I get is
32
How can I achieve something which I did in javaScript which is as follows,
var fn19 = function(){
var addNum = function(num){
var fn = function(num2){
fn.sum += num2;
return fn;
};
fn.sum = num;
return fn;
};
print("addNum(3)(4)(3)(10) ==> "+addNum(3)(4)(3)(10).sum);
};
fn19();
The output of the above code is
addNum(3)(4)(3)(10) ==> 20
Can I have the same kind of java function call where I can pass as many number arguments and the addFunction will add those many numbers.
Upvotes: 1
Views: 249
Reputation: 298183
An example, as close as possible to your JavaScript code, would be
class QuestionableConstruct {
int sum;
QuestionableConstruct add(int num2) {
sum += num2;
return this;
}
}
Runnable fn19 = () -> {
IntFunction<QuestionableConstruct> addNum = num -> {
QuestionableConstruct fn = new QuestionableConstruct();
fn.sum = num;
return fn;
};
System.out.println("addNum(3)(4)(3)(10)==> "+addNum.apply(3).add(4).add(3).add(10).sum);
};
fn19.run();
A more Java like solution would be
interface Add {
int sum();
default Add add(int num) {
int sum = sum() + num;
return () -> sum;
}
static Add num(int num) {
return () -> num;
}
}
usable as
System.out.println("addNum(3)(4)(3)(10) ==> "+Add.num(3).add(4).add(3).add(10).sum());
Unlike the JavaScript construct, this uses real immutable functions. Consider
Add a = Add.num(1).add(2).add(3);
System.out.println("1+2+3+4+5 = "+a.add(4).add(5).sum());
System.out.println("1+2+3+10+20 = "+a.add(10).add(20).sum());
which works smoothly without interference.
But of course, if you just want to sum a variable number of items, use
System.out.println("addNum(3)(4)(3)(10) ==> "+IntStream.of(3, 4, 3, 10).sum());
or if you want a mutable accumulator, use
System.out.println("addNum(3)(4)(3)(10) ==> "+
IntStream.builder().add(3).add(4).add(3).add(10).build().sum());
which allows to keep the builder and pass it around.
Upvotes: 1
Reputation: 1281
The technique you're describing in the JavaScript world is taking advantage of a closure.
This is a nice side-effect of functions in JavaScript being first-class citizens. It's a way of associating functions with data in the enclosing scope and then being able to pass this association around without losing inner context. The most common/simple use of which is caching(its formal name being memoisation).
You would need functions(methods) in Java to be first class, but doing so would be redundant as classes by design are an entity which associates data and methods, making the whole concept of a closure in this context redundant.
Upvotes: 0
Reputation: 140457
You can't exactly do that in Java, what you are looking for is reducing a stream of values.
In other words: the "real" functional solution here isn't to call one method with multiple arguments. You rather have the values in some list, and then you define the function that "accumulates" over the content of that list, by applying a function on the elements.
See here for some examples.
Upvotes: 0