将Observable of List转换为Observable列表并在RxJava中合并

时间:2018-03-11 19:42:22

标签: java android rx-java rx-java2

我正在通过创建黑客新闻阅读器应用程序来学习Java。

我要做的是:

  1. def run(u): buff = [] lock.acquire() e = requests.post('#personal_url', data=mydata) print(e.text) print('----------------') lock.release() lock.acquire() f = requests.get('#personal_urlx') print(u + ' --> ' f.text) print('----------------') lock.release() 发送请求,返回In[2]: from itertools import combinations ...: ...: ...: def solution(nums): ...: result = [] ...: seen = set() ...: for p in combinations(range(len(nums)), r=2): ...: dex_1, dex_2 = p ...: if nums[dex_1] == nums[dex_2]: ...: continue ...: current = [] ...: for i, elem in enumerate(nums): ...: if i == dex_1: ...: current.append(elem + nums[dex_2]) ...: elif i != dex_2: ...: current.append(elem) ...: sorted_current = tuple(sorted(current)) ...: if sorted_current not in seen: ...: result.append(tuple(current)) ...: seen.add(sorted_current) ...: return result ...: In[3]: solution((15, 8, 8, 3)) Out[3]: [(23, 8, 3), (18, 8, 8), (15, 11, 8)] In[4]: solution((6, 5, 3, 8)) Out[4]: [(11, 3, 8), (9, 5, 8), (14, 5, 3), (6, 8, 8), (6, 13, 3), (6, 5, 11)] ,在何时发出 请求完成。
  2. 将每个/topstories映射到Observable<List<int>>
  3. 在所有请求完成后,将Observable合并为一个实体storyId
  4. 代码:

    Observable<Story>

    然后我们会使用它:

    List<Story>

2 个答案:

答案 0 :(得分:4)

你可以尝试类似的东西

Observable<List<Integers>> ids = getIdsObservable();
Single<List<Story>> listSingle =
            ids.flatMapIterable(ids -> ids)
            .flatMap(id -> getStoryById(id)).toList();

然后您可以订阅该单身来获取List<Story>

答案 1 :(得分:0)

请查看我的解决方案。我更改了你的接口,为getStoryById()返回一个Single,因为它应该只返回一个值。之后,我为每个Story创建了一个Single请求,并使用Single.zip订阅了所有这些请求。当所有单打结束时,Zip将执行给定的lambda。缺点是,所有请求将立即被触发。如果你不想这样,我会更新我的帖子。请注意@elmorabea解决方案还将订阅前128个元素(BUFFER_SIZE = Math.max(1,Integer.getInteger(&#34; rx2.buffer-size&#34;,128));),以及一个完成时的下一个元素。

@Test
  void name() {
    Api api = mock(Api.class);

    when(api.getTopStories()).thenReturn(Flowable.just(Arrays.asList(new Story(1), new Story(2))));
    when(api.getStoryById(eq(1))).thenReturn(Single.just(new Story(888)));
    when(api.getStoryById(eq(2))).thenReturn(Single.just(new Story(888)));

    Flowable<List<Story>> listFlowable =
        api.getTopStories()
            .flatMapSingle(
                stories -> {
                  List<Single<Story>> collect =
                      stories
                          .stream()
                          .map(story -> api.getStoryById(story.id))
                          .collect(Collectors.toList());

                  // possibly not the best idea to subscribe to all singles at the same time
                  Single<List<Story>> zip =
                      Single.zip(
                          collect,
                          objects -> {
                            return Arrays.stream(objects)
                                .map(o -> (Story) o)
                                .collect(Collectors.toList());
                          });

                  return zip;
                });

    TestSubscriber<List<Story>> listTestSubscriber =
        listFlowable.test().assertComplete().assertValueCount(1).assertNoErrors();

    List<List<Story>> values = listTestSubscriber.values();

    List<Story> stories = values.get(0);

    assertThat(stories.size()).isEqualTo(2);
    assertThat(stories.get(0).id).isEqualTo(888);
    assertThat(stories.get(1).id).isEqualTo(888);
  }

  interface Api {
    Flowable<List<Story>> getTopStories();

    Single<Story> getStoryById(int id);
  }

  static class Story {
    private final int id;

    Story(int id) {
      this.id = id;
    }
  }