到目前爲止,咱們看到的例子都還比較小,在這裏,咱們將探索能夠過濾掉不相關數據或將數據簡化爲所需的單個值。java
這裏的大多數操做符對於任何熟悉Java流或函數編程的人來講都是熟悉的。這裏的全部 operators 都返回一個新的observable,而且不影響原始的可觀測性。這一原則在整個 Rx 中都存在。observables 轉換每一次都會產生一個新的 observable ,而且保持原始的不受影響。原始 observable 的 Subscribers 應該不會注意到任何變化,可是咱們將在後面的章節中看到,保證這一點可能須要開發人員引發注意。程序員
這是一個適當的時間引入 marble diagrams 的概念。這是解釋Rx中的 operators 的一種流行方法,由於它們的直觀和圖形性質。它們在 RxJava 的文檔中有不少,咱們只有利用它們的解釋性質。格式基本上是不言自明的:時間從左向右流動,形狀表示值,斜槓是一個o nCompletion,X 是一個錯誤。運算符應用於頂部 sequence,結果是下面的 sequence 。編程
Filter接受一個謂詞函數,該謂詞函數對發出的每一個值作出一個布爾決策。若是斷定爲false,則篩選序列中省略該項。併發
public final Observable<T> filter(Func1<? super T,java.lang.Boolean> predicate)
咱們將使用過濾器建立一個數字序列,並過濾掉全部偶數,只保留奇數。函數
輸出:spa
distinct 篩選出去重的任何元素。索引
輸出:事件
一個 distinct 的重載須要一個 key 選擇器。對於每一個項,函數生成一個鍵,而後使用鍵來肯定。ip
在這個例子中,咱們使用第一個字符做爲一個 key。開發
輸出:
「Fourth」和「Fifth」被過濾掉,由於它們的第一個字符是‘f’,它已經出如今「First」。
有經驗的程序員已經知道,這個 operator 在內部維護一個 set,每一個惟一的值都經過 observable 的值傳遞,並根據它檢查每一個新的值。雖然 Rx 操做符巧妙地隱藏了這些東西,但您仍然應該意識到 Rx 操做符可能會有很大的成本,並考慮您正在使用它的內容。
distinctUntilChanged 和 distinct 不一樣之處在於,只有連續的不一樣的值纔會被過濾掉。
輸出:
distinctUntilChanged 也可使用 key selector。
輸出:
ignoreElements會忽略每個值,可是讓咱們經過onCompleted和onError。
輸出:
ignoreElements() 的做用和 filter(v -> false) 相似。
下一組方法用於根據項目索引在特定點上按特定點進行順序操做,或者先取第一部分或第二個子元素。take 取前 n 個元素,skip 是跳過他們,注意,若是序列中的項少於指定索引,則兩個函數都認爲它是錯誤。
輸出:
java 8 stream 的使用者應該知道 limit 的操做符,在rx中也存在這樣的運算符,take 就是這樣一個別名,咱們很快也會看到更多的重載方法。
一旦第n項可用,take 方法當即完成.。若是發生錯誤,錯誤將被轉發,但若是發生在切點以後,take 方法則不會關心。
輸出:
skip 返回 take 的另外一半:
輸出:
這裏有些重載方法限制了時間
輸出:
take 和 skip 使用預約義索引工做。若是您想要「發現」截止點,當值出現時,takeWhile和skipWhile將使用謂詞。
Observable<T> takeWhile(Func1<? super T,java.lang.Boolean> predicate)
輸出:
如你所想的同樣,skipWhile 返回另外一半:
輸出:
skipLast 和 takeLast 做用相似於 take 和 skip ,不一樣之處在於結束的位置:
輸出:
還有兩種方法:takeUntil和skipUntil。takeUntil工做徹底相似於takeWhile謂詞返回false的狀況,skipUntil是true的狀況。
除此以外,takeUntil 和 skipUntil 都有一個很是有趣的重載,臨界點被定義爲另外一個 observable 發射一個值時。
輸出:
您可能還記得,這裏的計時器將等待250 ms併發出一個事件。這意味着要中止序列。請注意,信號能夠是任何類型的,由於實際值不被使用。
skipUntil 按照相同的規則工做,並返回 observable 另外一半。值被忽略直到信號開始讓值經過。
輸出: