2015-11-20 84 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) - 創建地圖