Наблюдаемый # take (Long) не возвращает желаемый размер элементов в RxJava

Я использую RxJava / Kotlin Observable#take(), чтобы получить первые 50 элементов из списка. Но оператор #take() ведет себя не так, как должно, в соответствии с документами Rx.

В документации Rx #take() определяется как:

"Emit only the first n items emitted by an Observable"

Наблюдаемый # take (Long) не возвращает желаемый размер элементов в RxJava

У меня есть такая функция:

Как мы видим, аргумент pageSize - это 50.

Наблюдаемый # take (Long) не возвращает желаемый размер элементов в RxJava

И начальный size из list - это 300.

Наблюдаемый # take (Long) не возвращает желаемый размер элементов в RxJava

После этого #take(50) применяется к этому Observable, и на следующей точке останова я все еще получаю список полный размерi.e. size = 300

Наблюдаемый # take (Long) не возвращает желаемый размер элементов в RxJava

Но just for the check, если что-то не так с отладчиком или наблюдаемым, я попытался взять только элементы, displayName которых содержит «9», но на этот раз я получаю ожидаемый результат smaller list с 9 в каждом из их #displayName field.

Наблюдаемый # take (Long) не возвращает желаемый размер элементов в RxJava

Я считаю, что оператор RxJava/Kotlin's #take() не такой уж сумасшедший, и это только я.

Я не уверен, но я думаю, что вы путаете две разные вещи, здесь оператор Observable.take() рассматривает выбросы наблюдаемого, а не размер излучаемого списка. Таким образом, если ваш remoteFollowersService.getFollowers() будет выдавать более 50 элементов, он вернет только первые 50 из них.

iluu 17.11.2018 17:11
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
1
375
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Внимательно посмотрите на тип возвращаемого значения вашего метода - Single<List<FollowersEntity>>. Observable, возвращаемый из remoteFollowersService.getFollowers(), - это нет, Observable, который испускает 300 элементов FollowersEntity - это Observable, который излучает элемент не замужем, и этот единственный элемент - это List, содержащий 300 элементов FollowersEntity. Другими словами, вам нужно вызывать дубль по списку, а не по наблюдаемому.

    return remoteFollowersService.getFollowers()
        .map { val size = it.size; it } // for debugging
        .map { it.take(pageSize) }
        .map { val size = it.size; it } // for debugging
        .map { it.filter { item -> item.displayName.contains("9") } }
        .single(emptyList())
Ответ принят как подходящий

take ведет себя правильно, так как даст вам только 50 «шариков» List<FollowersEntry>. Судя по вашим скриншотам и формулировкам, я предполагаю, что вы хотели 50 FollowersEntry. Между контейнером объектов и самими объектами есть фундаментальное логическое различие. RxJava видит только последовательность объектов типа List<>, но не может знать о вложенных объектах, с которыми вы намеревались работать.

Следовательно, вам нужно либо использовать it.take(50) внутри map (или любую другую функцию коллекций Kotlin), либо развернуть последовательность списков в последовательность записей через flatMapIterable:

getFollowers()
.flatMapIterable(entry -> entry)
.take(50 /* entries this time, not lists */)

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

erluxman 17.11.2018 17:17

Другие вопросы по теме