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?
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);
}