Search code examples
javajava-8functional-programmingfunctional-java

How we I achieve add(4)(10)(20)(3)(1).total using Java Function?


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.


Solution

  • 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.