Есть ли способ сгруппировать значения, а затем рассчитать сумму с помощью RxJava - PullRequest
1 голос
/ 22 мая 2019

У меня есть список объектов в форме Flowable.Пример -

values count
A      2
B      3
C      4
A      5
C      1

Я хочу сгруппировать текучую среду на основе значений, а затем вычислить сумму.Есть ли лучший способ сделать это?

Я уже пытался генерировать мультикарту.Затем определение функции в подписчике для агрегирования результатов.Однако я чувствую, что не использую JavaRx эффективно для агрегации в потоках.

 Flowable<Response> responseFlowable = Flowable.fromIterable(generateList());
        replayResponseFlowable.toMultimap(response -> response.getValues(), response -> response.getCount()).subscribe(groups-> calculateSum(groups));

    }

    private static void calculateSum(Map<String,Collection<Integer>> groups) 
   {
      //iterate over the map and calculate sum for each of the groups.  
   }        

Ожидаемый результат:

A      7
B      3
C      5

Я хочу выполнить это вычисление в потоке с использованием JavaRx.вместо определения пользовательского метода.Как я могу это сделать?

1 Ответ

1 голос
/ 23 мая 2019

Вы можете поместить calculateSum в поток, чтобы он выглядел лучше.

replayResponseFlowable.toMultiMap(response -> response.getValues())
    .map(groups -> calculateSum(groups))
    .subscribe(result -> {
        print(result);
    })


Поскольку вы только агрегируете счетчики, вам не нужноотслеживать все предметы.Вместо этого вы можете оставить только сумму отсчета для каждого значения.Это можно сделать с помощью оператора .collect:

replayResponseFlowable
    .collectInto(new HashMap<String, Integer>(), (group, response) -> {
         group.merge(response.values, response.count, Integer::sum);
    })
    .subscribe(result -> {
        print(result);
    });

Это выведет

emitted=[{value=A, count=7}, {value=B, count=3}, {value=C, count=5}]


Если вы хотите получить результат в виде текущегоиспускает предметы, используйте .scan:

    replayResponseFlowable
            .scan(new HashMap<String, Integer>(), (group, response) -> {
                group.merge(response.values, response.count, Integer::sum);
                return group;
            })
            .subscribe(result -> {
                print(result);
            });

Это напечатает:

emitted=[]
emitted=[{value=A, count=2}]
emitted=[{value=A, count=2}, {value=B, count=3}]
emitted=[{value=A, count=2}, {value=B, count=3}, {value=C, count=4}]
emitted=[{value=A, count=7}, {value=B, count=3}, {value=C, count=4}]
emitted=[{value=A, count=7}, {value=B, count=3}, {value=C, count=5}]
...