轉載請註明出處:https://zhuanlan.zhihu.com/p/20687178java
RxJava系列3(轉換操做符)github
提高開發效率,下降維護成本一直是開發團隊永恆不變的宗旨。近一年來國內的技術圈子中愈來愈多的開始說起Rx,通過一段時間的學習和探索以後我也深深的感覺到了RxJava的魅力。它能幫助咱們簡化代碼邏輯,提高代碼可讀性。這對於開發效率的提高、後期維護成本的下降幫助都是巨大的。我的預測RxJava必定是2016年的一個大趨勢,因此也有打算將它引入到公司現有的項目中來,寫這一系列的文章主要也是爲了團隊內部作技術分享。ide
因爲我本人是個Android程序猿,所以這一系列文章中的場景都是基於Android平臺的。若是你是個Java Web工程師或者是其它方向的那也不要緊,我會盡可能用通俗的語言將問題描述清楚。post
在介紹RxJava前,咱們先聊聊響應式編程。那麼什麼是響應式編程呢?響應式編程是一種基於異步數據流概念的編程模式。數據流就像一條河:它能夠被觀測,被過濾,被操做,或者爲新的消費者與另一條流合併爲一條新的流。
響應式編程的一個關鍵概念是事件。事件能夠被等待,能夠觸發過程,也能夠觸發其它事件。事件是惟一的以合適的方式將咱們的現實世界映射到咱們的軟件中:若是屋裏太熱了咱們就打開一扇窗戶。一樣的,當咱們的天氣app從服務端獲取到新的天氣數據後,咱們須要更新app上展現天氣信息的UI;汽車上的車道偏移系統探測到車輛偏移了正常路線就會提醒駕駛者糾正,就是是響應事件。
今天,響應式編程最通用的一個場景是UI:咱們的移動App必須作出對網絡調用、用戶觸摸輸入和系統彈框的響應。在這個世界上,軟件之因此是事件驅動並響應的是由於現實生活也是如此。
本章節中部分概念摘自《RxJava Essentials》一書
Rx是微軟.Net的一個響應式擴展,Rx藉助可觀測的序列提供一種簡單的方式來建立異步的,基於事件驅動的程序。2012年Netflix爲了應對不斷增加的業務需求開始將.NET Rx遷移到JVM上面。並於13年二月份正式向外展現了RxJava。
從語義的角度來看,RxJava就是.NET Rx。從語法的角度來看,Netflix考慮到了對應每一個Rx方法,保留了Java代碼規範和基本的模式。
那麼到底什麼是RxJava呢?我對它的定義是:RxJava本質上是一個異步操做庫,是一個能讓你用極其簡潔的邏輯去處理繁瑣複雜任務的異步事件庫。
Android平臺上爲已經開發者提供了AsyncTask,Handler等用來作異步操做的類庫,那咱們爲何還要選擇RxJava呢?答案是簡潔!RxJava能夠用很是簡潔的代碼邏輯來解決複雜問題;並且即便業務邏輯的愈來愈複雜,它依然可以保持簡潔!再配合上Lambda用簡單的幾行代碼分分鐘就解決你負責的業務問題。簡直逼格爆表,拿它裝逼那是極好的!
多說無益,上代碼!
假設咱們安居客用戶App上有個需求,須要從服務端拉取上海浦東新區塘橋板塊的全部小區Community[] communities,每一個小區下包含多套房源List<House> houses;咱們須要把塘橋板塊的全部總價大於500W的房源都展現在App的房源列表頁。用於從服務端拉取communities須要發起網絡請求,比較耗時,所以須要在後臺運行。而這些房源信息須要展現到App的頁面上,所以須要在UI線程上執行。(此例子思路來源於扔物線的給Android開發者的RxJava詳解一文)
new Thread() { @Override public void run() { super.run(); //從服務端獲取小區列表 List<Community> communities = getCommunitiesFromServer(); for (Community community : communities) { List<House> houses = community.houses; for (House house : houses) { if (house.price >= 5000000) { runOnUiThread(new Runnable() { @Override public void run() { //將房子的信息添加到屏幕上 addHouseInformationToScreen(house); } }); } } } } }.start();
使用RxJava的寫法是這樣的:
Observable.from(getCommunitiesFromServer()) .flatMap(new Func1<Community, Observable<House>>() { @Override public Observable<House> call(Community community) { return Observable.from(community.houses); } }).filter(new Func1<House, Boolean>() { @Override public Boolean call(House house) { return house.price>=5000000; } }).subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<House>() { @Override public void call(House house) { //將房子的信息添加到屏幕上 addHouseInformationToScreen(house); } });
從上面這段代碼咱們能夠看到:雖然代碼量看起來變複雜了,可是RxJava的實現是一條鏈式調用,沒有任何的嵌套;整個實現邏輯看起來異常簡潔清晰,這對咱們的編程實現和後期維護是有巨大幫助的。特別是對於那些回調嵌套的場景。配合Lambda表達式還能夠簡化成這樣:
Observable.from(getCommunitiesFromServer()) .flatMap(community -> Observable.from(community.houses)) .filter(house -> house.price>=5000000).subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(this::addHouseInformationToScreen);
簡潔!有美感!這纔是一個有情懷的程序員應該寫出來的代碼。
看完這篇文章你們應該可以理解RxJava爲何會愈來愈火了。它能極大的提升咱們的開發效率和代碼的可讀性!固然了RxJava的學習曲線也是比較陡的,在後面的文章我會對主要的知識點作詳細的介紹,敬請關注!
若是你們喜歡這一系列的文章,歡迎關注個人知乎專欄和GitHub。