Нужен простой пример map() reduce() с RXJava на Android без лямбда-выражений Java 8

Я пытаюсь применить RXJava в приложении для Android без Java 8, то есть я не могу использовать лямбда-функции. В качестве теста, чтобы убедиться, что я понимаю основы, я просто хотел бы увидеть простой пример с использованием map() и reduce().

Пример, который я пытаюсь реализовать, заключается в суммировании целых чисел, представленных в виде списка типа String. Я хотел бы обернуть все это в функцию, которую можно вызвать для получения суммы без того, чтобы вызывающая функция понимала, что функция реализована с помощью функционального программирования.

Я реализовал следующее, но это кажется слишком сложным. Например, мне пришлось сделать finalSum массивом, потому что ошибка: невозможно назначить значение для конечной переменной.

Я чувствую, что это слишком сложно, потому что я, возможно, неправильно понял что-то фундаментальное о функциональном программировании / ReactiveX / функциональном реактивном программировании / и т. д.

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];
}

У кого-нибудь есть более простое решение?


person Michael Osofsky    schedule 28.04.2017    source источник
comment
Я не эксперт по RxJava, но на самом деле я бы вернул Observable‹Integer› из sumStringOfInts() и подписался на него, когда мне нужно выполнить операцию. Вам не нужно было бы делать этот трюк с Integer[] (который не сработал бы, если бы вы подписались на другой поток).   -  person mVck    schedule 28.04.2017


Ответы (1)


это кажется слишком сложным

Лямбда-выражения помогают писать более чистый код.

Я не могу использовать лямбда-функции. В качестве теста, чтобы убедиться, что я понимаю основы

В этом случае вы получаете много шаблонов. Кроме того, многие IDE позволяют вам писать лямбда-выражения даже в проекте Java 7 и предлагают быстрое исправление превращения его в анонимный внутренний класс.

Мне пришлось сделать finalSum массивом

toBlocking().firstOrDefault(null) даст вам результат операции сокращения, при необходимости заблокировав ее:

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

У кого-нибудь есть более простое решение?

Вы можете заменить часть reduce на MathObservable.sumInt() из библиотеки RxJavaMath, но это не намного красивее:

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);
}
person akarnokd    schedule 28.04.2017