最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java的RxJava庫操作符的用法及實例講解

 更新時間:2016年06月18日 11:59:38   作者:hi大頭鬼hi  
RxJava由于提供異步和基于事件的支持在Android開發(fā)者中獲得了不少人氣,這里我們就來看一下Java的RxJava庫操作符的用法及實例講解,需要的朋友可以參考下

操作符就是為了解決對Observable對象的變換的問題,操作符用于在Observable和最終的Subscriber之間修改Observable發(fā)出的事件。RxJava提供了很多很有用的操作符。
比如map操作符,就是用來把把一個事件轉(zhuǎn)換為另一個事件的。

Observable.just("Hello, world!") 
 .map(new Func1<String, String>() { 
   @Override 
   public String call(String s) { 
     return s + " -Dan"; 
   } 
 }) 
 .subscribe(s -> System.out.println(s)); 

使用lambda可以簡化為

 
Observable.just("Hello, world!") 
  .map(s -> s + " -Dan") 
  .subscribe(s -> System.out.println(s)); 

是不是很酷?map()操作符就是用于變換Observable對象的,map操作符返回一個Observable對象,這樣就可以實現(xiàn)鏈式調(diào)用,在一個Observable對象上多次使用map操作符,最終將最簡潔的數(shù)據(jù)傳遞給Subscriber對象。


map操作符進階
map操作符更有趣的一點是它不必返回Observable對象返回的類型,你可以使用map操作符返回一個發(fā)出新的數(shù)據(jù)類型的observable對象。
比如上面的例子中,subscriber并不關(guān)心返回的字符串,而是想要字符串的hash值
 

Observable.just("Hello, world!") 
  .map(new Func1<String, Integer>() { 
    @Override 
    public Integer call(String s) { 
      return s.hashCode(); 
    } 
  }) 
  .subscribe(i -> System.out.println(Integer.toString(i))); 

很有趣吧?我們初始的Observable返回的是字符串,最終的Subscriber收到的卻是Integer,當(dāng)然使用lambda可以進一步簡化代碼:
 

Observable.just("Hello, world!") 
  .map(s -> s.hashCode()) 
  .subscribe(i -> System.out.println(Integer.toString(i))); 

前面說過,Subscriber做的事情越少越好,我們再增加一個map操作符
 

Observable.just("Hello, world!") 
  .map(s -> s.hashCode()) 
  .map(i -> Integer.toString(i)) 
  .subscribe(s -> System.out.println(s)); 

不服?
是不是覺得我們的例子太簡單,不足以說服你?你需要明白下面的兩點:
1.Observable和Subscriber可以做任何事情
Observable可以是一個數(shù)據(jù)庫查詢,Subscriber用來顯示查詢結(jié)果;Observable可以是屏幕上的點擊事件,Subscriber用來響應(yīng)點擊事件;Observable可以是一個網(wǎng)絡(luò)請求,Subscriber用來顯示請求結(jié)果。
2.Observable和Subscriber是獨立于中間的變換過程的。
在Observable和Subscriber中間可以增減任何數(shù)量的map。整個系統(tǒng)是高度可組合的,操作數(shù)據(jù)是一個很簡單的過程。

實例
1.準備工作
假設(shè)我有這樣一個方法:
這個方法根據(jù)輸入的字符串返回一個網(wǎng)站的url列表(啊哈,搜索引擎)
 

Observable<List<String>> query(String text);  

現(xiàn)在我希望構(gòu)建一個健壯系統(tǒng),它可以查詢字符串并且顯示結(jié)果。根據(jù)上一篇blog的內(nèi)容,我們可能會寫出下面的代碼:
 

query("Hello, world!") 
  .subscribe(urls -> { 
    for (String url : urls) { 
      System.out.println(url); 
    } 
  }); 

這種代碼當(dāng)然是不能容忍的,因為上面的代碼使我們喪失了變化數(shù)據(jù)流的能力。一旦我們想要更改每一個URL,只能在Subscriber中來做。我們竟然沒有使用如此酷的map()操作符!?。?/p>

當(dāng)然,我可以使用map操作符,map的輸入是urls列表,處理的時候還是要for each遍歷,一樣很蛋疼。

萬幸,還有Observable.from()方法,它接收一個集合作為輸入,然后每次輸出一個元素給subscriber:
 

Observable.from("url1", "url2", "url3") 
  .subscribe(url -> System.out.println(url)); 

我們來把這個方法使用到剛才的場景: 

query("Hello, world!") 
  .subscribe(urls -> { 
    Observable.from(urls) 
      .subscribe(url -> System.out.println(url)); 
  }); 


雖然去掉了for each循環(huán),但是代碼依然看起來很亂。多個嵌套的subscription不僅看起來很丑,難以修改,更嚴重的是它會破壞某些我們現(xiàn)在還沒有講到的RxJava的特性。

2.改進
救星來了,他就是flatMap()。
Observable.flatMap()接收一個Observable的輸出作為輸入,同時輸出另外一個Observable。直接看代碼:

query("Hello, world!") 
  .flatMap(new Func1<List<String>, Observable<String>>() { 
    @Override 
    public Observable<String> call(List<String> urls) { 
      return Observable.from(urls); 
    } 
  }) 
  .subscribe(url -> System.out.println(url)); 

這里我貼出了整個的函數(shù)代碼,以方便你了解發(fā)生了什么,使用lambda可以大大簡化代碼長度:

 query("Hello, world!") 
  .flatMap(urls -> Observable.from(urls)) 
  .subscribe(url -> System.out.println(url)); 

flatMap()是不是看起來很奇怪?為什么它要返回另外一個Observable呢?理解flatMap的關(guān)鍵點在于,flatMap輸出的新的Observable正是我們在Subscriber想要接收的。現(xiàn)在Subscriber不再收到List<String>,而是收到一些列單個的字符串,就像Observable.from()的輸出一樣。

這部分也是我當(dāng)初學(xué)RxJava的時候最難理解的部分,一旦我突然領(lǐng)悟了,RxJava的很多疑問也就一并解決了。

3.還可以更好
flatMap()實在不能更贊了,它可以返回任何它想返回的Observable對象。
比如下面的方法: 

// 返回網(wǎng)站的標題,如果404了就返回null 
Observable<String> getTitle(String URL); 


接著前面的例子,現(xiàn)在我不想打印URL了,而是要打印收到的每個網(wǎng)站的標題。問題來了,我的方法每次只能傳入一個URL,并且返回值不是一個String,而是一個輸出String的Observabl對象。使用flatMap()可以簡單的解決這個問題。 

query("Hello, world!") 
  .flatMap(urls -> Observable.from(urls)) 
  .flatMap(new Func1<String, Observable<String>>() { 
    @Override 
    public Observable<String> call(String url) { 
      return getTitle(url); 
    } 
  }) 
  .subscribe(title -> System.out.println(title)); 

4.使用lambda:

query("Hello, world!") 
  .flatMap(urls -> Observable.from(urls)) 
  .flatMap(url -> getTitle(url)) 
  .subscribe(title -> System.out.println(title)); 

是不是感覺很不可思議?我竟然能將多個獨立的返回Observable對象的方法組合在一起!帥呆了!
不止這些,我還將兩個API的調(diào)用組合到一個鏈式調(diào)用中了。我們可以將任意多個API調(diào)用鏈接起來。大家應(yīng)該都應(yīng)該知道同步所有的API調(diào)用,然后將所有API調(diào)用的回調(diào)結(jié)果組合成需要展示的數(shù)據(jù)是一件多么蛋疼的事情。這里我們成功的避免了callback hell(多層嵌套的回調(diào),導(dǎo)致代碼難以閱讀維護)?,F(xiàn)在所有的邏輯都包裝成了這種簡單的響應(yīng)式調(diào)用。

5.豐富的操作符
目前為止,我們已經(jīng)接觸了兩個操作符,RxJava中還有更多的操作符,那么我們?nèi)绾问褂闷渌牟僮鞣麃砀倪M我們的代碼呢?
getTitle()返回null如果url不存在。我們不想輸出"null",那么我們可以從返回的title列表中過濾掉null值!

query("Hello, world!") 
  .flatMap(urls -> Observable.from(urls)) 
  .flatMap(url -> getTitle(url)) 
  .filter(title -> title != null) 
  .subscribe(title -> System.out.println(title)); 

filter()輸出和輸入相同的元素,并且會過濾掉那些不滿足檢查條件的。

如果我們只想要最多5個結(jié)果:
 

query("Hello, world!") 
  .flatMap(urls -> Observable.from(urls)) 
  .flatMap(url -> getTitle(url)) 
  .filter(title -> title != null) 
  .take(5) 
  .subscribe(title -> System.out.println(title)); 

take()輸出最多指定數(shù)量的結(jié)果。

如果我們想在打印之前,把每個標題保存到磁盤: 

query("Hello, world!") 
  .flatMap(urls -> Observable.from(urls)) 
  .flatMap(url -> getTitle(url)) 
  .filter(title -> title != null) 
  .take(5) 
  .doOnNext(title -> saveTitle(title)) 
  .subscribe(title -> System.out.println(title)); 

doOnNext()允許我們在每次輸出一個元素之前做一些額外的事情,比如這里的保存標題。

看到這里操作數(shù)據(jù)流是多么簡單了么。你可以添加任意多的操作,并且不會搞亂你的代碼。

RxJava包含了大量的操作符。操作符的數(shù)量是有點嚇人,但是很值得你去挨個看一下,這樣你可以知道有哪些操作符可以使用。弄懂這些操作符可能會花一些時間,但是一旦弄懂了,你就完全掌握了RxJava的威力。

你甚至可以編寫自定義的操作符!這篇blog不打算將自定義操作符,如果你想的話,清自行Google吧。

感覺如何?
好吧,你是一個懷疑主義者,并且還很難被說服,那為什么你要關(guān)心這些操作符呢?

因為操作符可以讓你對數(shù)據(jù)流做任何操作。

將一系列的操作符鏈接起來就可以完成復(fù)雜的邏輯。代碼被分解成一系列可以組合的片段。這就是響應(yīng)式函數(shù)編程的魅力。用的越多,就會越多的改變你的編程思維。

另外,RxJava也使我們處理數(shù)據(jù)的方式變得更簡單。在最后一個例子里,我們調(diào)用了兩個API,對API返回的數(shù)據(jù)進行了處理,然后保存到磁盤。但是我們的Subscriber并不知道這些,它只是認為自己在接收一個Observable<String>對象。良好的封裝性也帶來了編碼的便利!


在第三部分中,我將介紹RxJava的另外一些很酷的特性,比如錯誤處理和并發(fā),這些特性并不會直接用來處理數(shù)據(jù)。

相關(guān)文章

  • 使用java執(zhí)行定時任務(wù)示例

    使用java執(zhí)行定時任務(wù)示例

    這篇文章主要介紹了使用java執(zhí)行定時任務(wù)示例,需要的朋友可以參考下
    2014-04-04
  • 使用jps命令查看Java進程的詳細指南

    使用jps命令查看Java進程的詳細指南

    jps是Java開發(fā)者和系統(tǒng)管理員的得力助手,它簡化了Java進程監(jiān)控的過程,使得快速檢查應(yīng)用運行狀態(tài)變得輕而易舉,在Java開發(fā)和運維場景中,jps是一個非常實用的命令行工具,本文介紹了如何有效地使用 jps命令來查看Java進程的詳細指南,需要的朋友可以參考下
    2024-10-10
  • java中JDBC增刪改查操作詳解

    java中JDBC增刪改查操作詳解

    大家好,本篇文章主要講的是java中JDBC增刪改查操作詳解,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • 關(guān)于使用jpa聚合函數(shù)遇到的問題

    關(guān)于使用jpa聚合函數(shù)遇到的問題

    這篇文章主要介紹了關(guān)于使用jpa聚合函數(shù)遇到的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Maven依賴沖突的幾種有效解決方法總結(jié)

    Maven依賴沖突的幾種有效解決方法總結(jié)

    在項目開發(fā)中使用Maven管理Jar包時,常常會遇到Jar包依賴沖突,所以本文就給大家總結(jié)了幾種解決Maven依賴沖突的有效方法,需要的朋友可以參考下
    2023-07-07
  • Java Hutool 包工具類推薦 ExcelUtil詳解

    Java Hutool 包工具類推薦 ExcelUtil詳解

    這篇文章主要介紹了Java Hutool 包工具類推薦 ExcelUtil詳解,需要引入hutool包,版本號可根據(jù)實際情況更換,除hutool包之外,還需要引入操作Excel必要包,本文給大家介紹的非常詳細,需要的朋友可以參考下
    2022-09-09
  • Java+Selenium實現(xiàn)控制瀏覽器的啟動選項Options

    Java+Selenium實現(xiàn)控制瀏覽器的啟動選項Options

    這篇文章主要為大家詳細介紹了如何使用java代碼利用selenium控制瀏覽器的啟動選項Options的代碼操作,文中的示例代碼講解詳細,感興趣的可以了解一下
    2023-01-01
  • 淺析Java中的XML文件處理

    淺析Java中的XML文件處理

    ?XML?是一種用于存儲和傳輸數(shù)據(jù)的標記語言,由W3C(萬維網(wǎng)聯(lián)盟)于1998年發(fā)布,本文主要來和大家聊聊Java中XML文件處理的相關(guān)知識,有需要的可以參考下
    2024-11-11
  • SpringBoot整合Thymeleaf的方法

    SpringBoot整合Thymeleaf的方法

    這篇文章主要介紹了SpringBoot整合Thymeleaf的方法,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下,希望能夠幫助到你
    2021-07-07
  • SpringBoot 如何讀取classpath下的文件

    SpringBoot 如何讀取classpath下的文件

    這篇文章主要介紹了SpringBoot 讀取classpath下的文件方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06

最新評論

安国市| 江华| 成都市| 大埔县| 三江| 金平| 崇义县| 福清市| 郯城县| 郓城县| 炎陵县| 砀山县| 威宁| 赫章县| 县级市| 唐河县| 金寨县| 成安县| 上犹县| 奉贤区| 晋城| 绥德县| 临西县| 云浮市| 吴桥县| 化州市| 盐边县| 麦盖提县| 白朗县| 顺平县| 突泉县| 靖安县| 新化县| 忻城县| 易门县| 晋宁县| 蓬安县| 米泉市| 康马县| 湖南省| 枣庄市|