国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - Java的RxJava庫操作符的用法及實例講解

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

2020-05-18 12:17hi大頭鬼hi JAVA教程

RxJava由于提供異步和基于事件的支持在Android開發者中獲得了不少人氣,這里我們就來看一下Java的RxJava庫操作符的用法及實例講解,需要的朋友可以參考下

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

?
1
2
3
4
5
6
7
8
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可以簡化為

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

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


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

?
1
2
3
4
5
6
7
8
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,當然使用lambda可以進一步簡化代碼:
 

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

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

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

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

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

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

現在我希望構建一個健壯系統,它可以查詢字符串并且顯示結果。根據上一篇blog的內容,我們可能會寫出下面的代碼:
 

?
1
2
3
4
5
6
query("Hello, world!")
  .subscribe(urls -> {
    for (String url : urls) {
      System.out.println(url);
    }
  });

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

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

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

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

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

?
1
2
3
4
5
query("Hello, world!")
  .subscribe(urls -> {
    Observable.from(urls)
      .subscribe(url -> System.out.println(url));
  });


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

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

?
1
2
3
4
5
6
7
8
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));

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

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

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

這部分也是我當初學RxJava的時候最難理解的部分,一旦我突然領悟了,RxJava的很多疑問也就一并解決了。

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

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


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

?
1
2
3
4
5
6
7
8
9
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:

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

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

5.豐富的操作符
目前為止,我們已經接觸了兩個操作符,RxJava中還有更多的操作符,那么我們如何使用其他的操作符來改進我們的代碼呢?
getTitle()返回null如果url不存在。我們不想輸出"null",那么我們可以從返回的title列表中過濾掉null值!

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

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

如果我們只想要最多5個結果:
 

?
1
2
3
4
5
6
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()輸出最多指定數量的結果。

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

?
1
2
3
4
5
6
7
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()允許我們在每次輸出一個元素之前做一些額外的事情,比如這里的保存標題。

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

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

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

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

因為操作符可以讓你對數據流做任何操作。

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

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


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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲一区二区视频 | 久久精品91久久久久久再现 | www.亚洲精品 | 精品成人久久 | 毛片黄片免费观看 | 精品久久久久久亚洲精品 | 日日久 | 欧美日韩a | 亚洲一区二区久久 | 国产精品99一区二区三区 | 国产精品五区 | 一大道一二三区不卡 | av永久 | 亚洲社区在线 | 久久久久久久国产 | 国产 欧美 日韩 一区 | 久久99操 | 国产一区二区h | 一级一片免费看 | 欧美视频精品在线观看 | 99精品一区二区三区 | 这里只有精品国产 | 亚洲国产精品无卡做爰天天 | 91精品国产欧美一区二区成人 | 国产精品二区一区二区aⅴ污介绍 | 蜜桃视频成人在线观看 | 精品亚洲一区二区 | 午夜精品久久久久久久久 | www.日韩 | 欧美久久久久 | 色综合欧美 | 久久国产精品久久久久久 | 亚洲国产一区二区三区精品 | 老妇女av | 91免费观看 | 99精品欧美一区二区三区综合在线 | 久久久久久免费精品 | 亚洲国产婷婷香蕉久久久久久99 | 久久精品一区二区 | 久久人人爽人人爽人人片亚洲 | 亚洲精品一区二区在线观看 |