Аналогичный код take () и groupBy () применяется к timer (), что приводит к различным результатам - PullRequest
0 голосов
/ 05 июня 2019

Следующие два фрагмента кода из репозитория Learnrxjava (https://github.com/jhusain/learnrxjava) дают разные результаты:

Observable.timer(0, 1, TimeUnit.MILLISECONDS)
                .groupBy(n -> n % 2 == 0)
                .flatMap(g -> {
                    return g.take(10).toList();
                }).take(2).toBlocking().forEach(System.out::println);

и

Observable.timer(0, 1, TimeUnit.MILLISECONDS)
                .take(20)
                .groupBy(n -> n % 2 == 0)
                .flatMap(g -> {
                    return g.toList();
                })
                .toBlocking()
                .forEach(System.out::println);

урожайность

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

и

[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

соответственно. Я просто не мог понять, почему результат переворачивается во втором случае.

Спасибо.

1 Ответ

0 голосов
/ 07 июня 2019

Основной причиной является внутреннее take, форсирующее передачу сигналов четной группы до завершения groupBy.

GroupBy содержит две группы на карте, которые имеют естественный порядок для false (нечетная группа) и true (четная группа) .

Когда источник излучает 18, true (четная) группа получает все свои 10 элементов и take выдает onCompleted, заканчивая список, который затем отправляется flatMap.Затем источник испускает 19, что завершает ложную (нечетную) группу и делает то же самое.

Когда нет внутреннего take, обе группы остаются активными, пока источник не завершит работу после 20Предметы.По завершении groupBy уведомляет ложную (нечетную) группу сначала о завершении, которое затем сначала генерирует нечетный список, затем true (четная) группа завершается, испускаячетный список.

...