Search code examples
androidrx-javajava-7reactivex

Need simple map() reduce() example with RXJava on Android without Java 8 lambdas


I'm trying to apply RXJava in an Android application without Java 8, meaning I can't use lambda functions. As a test to make sure I understand the basics, I'd just like to see a simple example using map() and reduce().

The example I'm trying to implement is to sum integers that are provided as a List of type String. I'd like to wrap the whole thing in a function that can be called to get the sum without the function caller needing to understand that the function is implemented with functional programming.

I've implemented the following but it seems overly complicated. For example, I had to make finalSum be an array because error: cannot assign a value to final variable.

I feel like it's overly complicated because I may have misunderstood something fundamental about functional programming / ReactiveX / functional reactive programming / etc.

public void mapReduceTest() {
    List<String> ints = new ArrayList<>();
    ints.add("10");
    ints.add("20");
    ints.add("30");

    System.out.println("finalSum[0] (should equal 60) = " + sumStringOfInts(ints));
}

public Integer sumStringOfInts(List<String> ints) {
    final Integer[] finalSum = new Integer[1];
    Observable.from(ints)
            .map(new Func1<String, Integer>() {

                @Override
                public Integer call(String s) {
                    return new Integer(s);
                }
            })
            .reduce(new Func2<Integer, Integer, Integer>() {
                @Override
                public Integer call(Integer x, Integer sum) {
                    return sum + x;
                }
            })
            .subscribe(new Action1<Integer>() {
                @Override
                public void call(Integer sum) {
                    finalSum[0] = sum;
                }
            });
    return finalSum[0];
}

Does anyone have a simpler solution?


Solution

  • it seems overly complicated

    Lambdas help you write much cleaner code.

    I can't use lambda functions. As a test to make sure I understand the basics

    You get a lot of boilerplate in this case. Plus many IDEs let you write a lambdas, even in a Java 7 project and offer quick-fix of turning it into an anonymous inner class.

    I had to make finalSum be an array

    The toBlocking().firstOrDefault(null) will get you the result of the reduce operation, blocking for it if necessary:

    public Integer sumStringOfInts(List<String> ints) {
         return Observable.from(ints)
            .map(new Func1<String, Integer>() {
                @Override
                public Integer call(String s) {
                    return Integer.parseInt(s);
                }
            })
            .reduce(new Func2<Integer, Integer, Integer>() {
                @Override
                public Integer call(Integer x, Integer sum) {
                    return sum + x;
                }
            })
            .toBlocking()
            .firstOrDefault(null);
    }
    

    Does anyone have a simpler solution?

    You can replace the reduce part with MathObservable.sumInt() from RxJavaMath library, but that's not much prettier:

    public Integer sumStringOfInts(List<String> ints) {
         return 
            MathObservable.sumInteger(
               Observable.from(ints)
               .map(new Func1<String, Integer>() {
                   @Override
                   public Integer call(String s) {
                       return Integer.parseInt(s);
                   }
               })
            )
            .toBlocking()
            .firstOrDefault(null);
    }