2015-11-20 80 views
4

我有一个从REST端点返回的列表。我需要将该列表分解成多个类别(类别是列表中每个条目的一个项目)。个别类别将被写入缓存,以便稍后进行更快速的查找。rxJava转换列表到地图

我不知道如果我能.MAP()中的条目,并提供多种过滤器()或某些类型的case语句把类别条目在正确的桶。

请问像这样的声音合理与rxJava实现?

UPDATE: 非工作版本

private Map<String, List<VideoMetadataInfoEntity>> buildCategories(Observable<List<VideoMetadataInfoEntity>> videoList) { 

    Map<String, List<VideoMetadataInfoEntity>> categoryMap = new HashMap<>(); 
    videoList 
      .flatMap(Observable::from) 
      .subscribe(videoMetadataInfoEntity -> mapCategory(videoMetadataInfoEntity, categoryMap)); 

    Observable.just(categoryMap) 
      .doOnNext(saveCategoriesToCacheAction); 

    return categoryMap; 
} 

这些火顺序,但是,这是我的理解,因为它未签约的结果,第二观察到的不发送任何东西saveCategoriesToCacheAction第一个可观察到的。

我开始觉得我应该修改我的缓存策略。该列表将始终具有所有的细节。该服务不会为我提供可用于上市的子集,然后再调用以获取完整详细信息。这是一个项目的完整列表或全部细节。这可能是一种更好的方法,可以将每个缓存分别缓存到他们自己的分类缓存中。我正在尝试执行映射,以便此网络调用可以返回所请求的类别,但随后的调用将来自缓存,直到缓存过期并且新的网络调用刷新为止。

+0

rx是一个很好的平行执行任务的地方。这里的并行性在哪里? –

回答

0

RxJava则多为异步消息处理,但它也拥护函数式编程原理也可以作为一个穷人的流API。如果你正在使用Java 8考虑使用流来完成这项工作,但是当你问这个问题时,我假设你正在使用Java 7.

要做你想做的事你可以尝试(原谅lambda,用它代替它

Observable.from(list).subscribe(item -> groupItemInCategoryBucket(item)); 

其中groupItemInCategoryBucket是你的方法包含switch语句或任何其他你有缓存项的方式:匿名内部类,如果你不使用Retrolambda)。

请注意,这相当于一个for循环,尽管在许多其他很好的语言中使用这种风格是习惯性的,但很多Java开发人员在看到这些代码时可能会有些困惑。

+0

我正在使用retrolambda,它是java7。这将在一个Android应用程序。我会试试这个。我需要在各个类别上执行一些其他任务,例如将其转储到磁盘和内存高速缓存,以使其不会在网络上不断调用。我希望我能够干净地或通过其他订阅建立此链。在某些情况下,仅需要列表,在其他情况下,需要分组。像这样的东西。谢谢。 – dmfrey

+0

不客气。希望它能奏效;如果没有,请更新您的问题,更详细地了解您希望执行的其他操作,以便我的答案更有帮助。 – memoizr

+0

我更新了我的问题。我想我需要改变我的方法。 – dmfrey

1

一般分组项的可以(这件事参观this page获取更多信息)使用GROUPBY操作来实现。

Map<Integer, List<Integer>> groupedValues = new HashMap<>(4); 
    Observable.range(1, 20) 
      .groupBy(i -> i % 2, i -> i) 
      .subscribe(go -> { 
       List<Integer> groupValues = new ArrayList<>(); 
       groupedValues.put(go.getKey(), groupValues); 
       go.subscribe(t -> add(t, groupValues)); 
      }); 

工作原理:

  • 首先,可观察到的发射的项目(这发生在range方法)1至20基于其 奇偶
  • 其然后被发射到单独的观测量(groupBy方法,此方法后,你GroupedObservable操作)
  • 然后您订阅分组观察到,接受(在用户onNext)单独观测将包含分组的项目和他们分组的关键。
  • 如果他们的内容不感兴趣,以防止内存泄漏,请记住订阅分组的observables或发布take(0)

    我不确定这是否是最有效的方式,并欢迎有关此解决方案的一些意见。

    3

    我的解决办法是:

    Observable.range(1, 20) 
          .groupBy(number -> number % 2) 
          .flatMap(groupedObservable -> groupedObservable.toList()) 
          .toMap(list -> list.get(0) % 2); 
    

    结果我有[{0=[2, 4, 6, 8, 10, 12, 14, 16, 18, 20], 1=[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]}]

    说明:

    • 范围(1,20) - 创建可观察到的,其发射第一20个数字
    • groupBy(number - > number%2) - 创建一个可观察组,发出组observable,其中每个组observable保存项目分组与分组功能(在这里它是X%2)
    • flatMap(groupedObservable - > groupedObservable.toList()) - 打开每个组成一个可观察发射其所有项目作为一个列表
    • toMap(列表 - >列表.get(0)%2) - 创建地图