首頁 > Java > java教程 > 深入淺出RxJava_05[轉換操作&數學運算]的程式碼詳細介紹

深入淺出RxJava_05[轉換操作&數學運算]的程式碼詳細介紹

黄舟
發布: 2017-03-04 09:54:53
原創
1340 人瀏覽過

本教學基於RxJava1.x版本進行全面講解,後續課程將陸續更新,敬請關注…

# #在觀察者和被觀察者之間,有些傳輸的資料需要進行轉換之後才能用,例如:有時候拿到的是學校的某個班級學生的名單,但是我們需要知道他們的語文成績排列。這樣就是需要將ArrayList轉換成ArrayList隊列。

下列提供了一系列的資料切換操作符:

  1. Buffer - 將發送的多個資料變成發送n個佇列的資料,每個佇列的最大長度為buffer()函數指定的參數大小。

  2. Window - 定期將來自原始Observable的資料分解為一個Observable視窗.

  3. Map - 將某個傳送的數據轉換成另外一個資料

  4. flatMap - 實際上就是將發送的一個類型的資料轉換成另一個資料類型的物件

  5. GroupBy - 根據指定的key將相同類型的傳送資料存入n個子Observable。

  6. Scan - 對所有的發送資料進行某個函數運行,將第n和第n+1項進行計算,計算後的結果再和n+2項進行運行,一次類推。

1.Buffer

例如下面的數據,分別發送三個字串

Observable.just("Hello Android !", "Hello Java", "Hello C");
登入後複製

如果我們在該被觀察者後面加上buffer操作符,並指定快取2項,代碼如下:

final Observable observable = Observable.just("Hello Android !", "Hello Java", "Hello C");
Observable> bufferObservable = observable.buffer(2);
登入後複製

那麼它會第一次發送2個List數據,分別是:

List<String>(){"Hello Android !", "Hello Java"}
List<String>(){"Hello C"}
登入後複製

下面的完整範例程式碼如下:

//这里模拟正常发送三个单一值的被观察者
final Observable observable = Observable.just("Hello Android !", "Hello Java", "Hello C");
//定义一个缓存的被观察者 每次缓存2个 缓存的数据自上面observable对象获取
Observable> bufferObservable = observable.buffer(2);
//订阅对象并获取缓存被观察者发送出来的数据
bufferObservable.subscribe(new Action1>() {
    @Override
    public void call(List strings) {
        Log.i(TAG, "call:--------");
        for (int i = 0; i < strings.size(); i++) {
            Log.i(TAG, "call: "+strings.get(i));
        }
    }
});
登入後複製

輸出

call:--------
call: Hello Android !
call: Hello Java
call:--------
call: Hello C
登入後複製

buffer()其實就是將發送的n個資料轉換成發送x個佇列

2.Window

#定期將來自原始Observable的資料分解為一個Observable窗口,發射這些窗口,而不是每次發射一項資料

Window和Buffer類似,但不是發射來自原始Observable的資料包,它發射的是Observables,這些Observables中的每一個都發射原始Observable資料的子集,最後發射一個onCompleted通知。

Observable.just(1, 2, 3, 4, 5)
//将一个Observable发射出去的数据分解为多个Observable对象 每个Observable发射2个数据
            .window(2)
            .subscribe(new Action1<Observable<Integer>>() {
                @Override
                public void call(Observable<Integer> innerObservable) {
                    Log.i(TAG, "call: ---------");
                    innerObservable.subscribe(new Action1<Integer>() {
                        @Override
                        public void call(Integer value) {
                            Log.i(TAG, "call: "+value);
                        }
                    });
                }
            });
登入後複製

輸出:

 call: ---------
 call: 1
 call: 2
 call: ---------
 call: 3
 call: 4
 call: ---------
 call: 5
登入後複製

3.Map

學校新生入住。在資料輸入的時候,發現張三的名字輸入出錯,應該改為張三豐。現在 我們要重新為他輸入訊息。程式碼如下:

private ArrayList initPersons() {
    ArrayList<Student> persons = new ArrayList<>();
    persons.add(new Student("张三", 16));
    persons.add(new Student("李四", 17));
    persons.add(new Student("王二麻子", 18));
    return persons;
}

ArrayList<Student> students = initPersons();
for (int i = 0; i < students.size(); i++) {
    Student student = students.get(i);
    if (student.name.equals("张三")){
        student.name="张三丰";
    }
}
登入後複製

RxJava這樣轉換:

Observable.from(initPersons())
            //将张三的名字改为张三丰
            .map(new Func1<Student, Student>() {
                @Override
                public Student call(Student student) {
                     //循环检查每个学生的名字,如果找到张三 则改为张三丰
                    if (student.name.equals("张三")){
                        student.name="张三丰";
                    }
                    return student;
                }
            })
            .subscribe(new Action1<Student>() {
                @Override
                public void call(Student student) {
                    Log.i(TAG, "call: "+student);
                }
            });
登入後複製

#map()其實就是將某個發送的資料轉換成另外一個資料## 4.FlatMap

今天學校組了體操隊。學校又招了幾個學生代碼如下:

private ArrayList<Student> initStudents() {
    ArrayList<Student> persons = new ArrayList<>();
    persons.add(new Student("张三", 11));
    persons.add(new Student("李四", 12));
    persons.add(new Student("王二麻子", 13));
    persons.add(new Student("李雷", 19));
    persons.add(new Student("韩梅梅", 18));
    persons.add(new Student("韩红", 17));
    return persons;
}
登入後複製

上級要求,學體操要從娃娃抓起,讓我們找出年齡小於15歲的學生,組成一個體操隊,並且給小學生創建一個特定的小學生類。

public static class LittleStudent extends Student{

    public LittleStudent(String name, int age) {
        super(name, age);
    }
}
登入後複製

於是程式碼如下:

ArrayList<Student> students = initStudents();

//封装小学生集合
ArrayList<LittleStudent> littleStudents=new ArrayList<>();
for (int i = 0; i < students.size(); i++) {
    Student student = students.get(i);
    if (student.age<15){
        littleStudents.add(new LittleStudent(student.name,student.age));
    }
}
登入後複製

RxJava這樣轉換:

Observable.from(initStudents())
            .flatMap(new Func1<Student, Observable<LittleStudent>>() {
                @Override
                public Observable<LittleStudent> call(Student student) {
                    if (student.age<15){
                        return Observable.just(new LittleStudent(student.name,student.age));
                    }
                    return null;
                }
            })
            .subscribe(new Action1<LittleStudent>() {
                @Override
                public void call(LittleStudent littleStudent) {
                    Log.i(TAG, "call: "+littleStudent);
                }
            });
登入後複製

flatMap()實際上就是將發送的一個類型的資料轉換成另外一個數據類型的物件

5.GroupBy

將一個Observable分拆為一些Observables集合,它們中的每一個發射原始Observable的一個子序列。哪一個資料項由哪一個Observable發射是由groupBy內部的函數判定的,這個函數給每一項指定一個Key,Key相同的資料會被同一個Observable發射。它傳回Observable的一個特殊子類別GroupedObservable,實作了GroupedObservable介面的物件有一個額外的方法getKey,這個Key用來將資料分組到指定的Observable。

//模拟学校录入的一系列的同名学生信息
private Observable<Person> getPersons(){
    return Observable.from(new Person[]{
            new Person("zhangsan",18),
            new Person("zhangsan",20),
            new Person("lisi",19),
            new Person("lisi",33),
            new Person("wangwu",20),
            new Person("wangwu",22),
            new Person("wangwu",21)
    });
}
登入後複製

實作歸類呼叫

final Observable<GroupedObservable<String, Person>> observable = getPersons()
        //根据用户的名称来归类
        .groupBy(new Func1<Person, String>() {
            @Override
            public String call(Person person) {
                return person.name;
            }
        });
observable.subscribe(new Action1<GroupedObservable<String, Person>>() {
    //每归一类 则调用一次该方法
    @Override
    public void call(GroupedObservable<String, Person> observablelist) {
        Log.i(TAG, "call: ----"+observablelist.getKey());
        //打印队列中的每个元素
        observablelist.subscribe(new Action1<Person>() {
            @Override
            public void call(Person person) {
                Log.i(TAG, "call: "+person.name+"  "+person.age);
            }
        });

    }
});
登入後複製

根據指定的key將相同類型的傳送資料存入n個子Observable

##6.Scan

Scan操作子對原始Observable發射的第一個資料應用一個函數,然後將那個函數的結果作為自己的第一個資料發射。它將函數的結果同第二項資料一起填入這個函數來產生它自己的第二項資料。它持續進行這個過程來產生剩餘的資料序列。這個運算子在某些情況下被叫做accumulator。

例如我們想從1加到5,思路是這樣的:

 1+2=3;
 3+3=6;
 6+4=10;
10+5=15;
登入後複製

RxJava這樣轉換:

//实现从1加到5的总数
Observable.just(1, 2, 3, 4, 5)
    .scan(new Func2<Integer, Integer, Integer>() {
        //定义每个子项的合并规则
        @Override
        public Integer call(Integer sum, Integer item) {
            return sum + item;
        }
    })
    .subscribe(new Action1<Integer>() {
        @Override
        public void call(Integer result) {
            Log.i(TAG, "call: " + result);
        }
    });
登入後複製

輸出

Next: 1
Next: 3
Next: 6
Next: 10
Next: 15
Sequence complete.
登入後複製

對所有的發送資料進行某個函數運行,將第n和第n+1項進行計算,計算後的結果再和n+2項進行運行,一次類推

   

##在開發的過程,不可避免的會使用某些常見的數學計算,例如計算一個隊列的平均數/求和/最大最小值/獲取個數等等

關於數學的計算,這裡RxJava提供了一個依賴包。其下載的位址是RxJavaMath

其開發套件提供了一個核心幫助類別:

MathObservable

7.Average求某個佇列的平均數,這個佇列可以是int型別也可以是double型別等。以下範例計算1到6的平均值

Observable<Integer> o1 = 
           MathObservable.averageInteger(Observable.just(1,2,3,4,5,6));
o1.subscribe(new Action1<Integer>() {
    @Override
    public void call(Integer integer) {
        Log.i(TAG, "call: "+integer);
    }
});
登入後複製

8.Max/Min

Min操作子操作一個發射數值的Observable並發射單一值:最小的那個值。

Max操作符操作一個發射數值的Observable並發射單一值:最大的那個值。

以下例子列出1到6的最小值:

Observable<Integer> o1 =
            MathObservable.min(Observable.just(1,2,3,4,5,6));

o1.subscribe(new Action1<Integer>() {
    @Override
    public void call(Integer integer) {
        Log.i(TAG, "call: "+integer);
    }
});
登入後複製

以下例子列出1到6的最大值:

Observable<Integer> o1 =
            MathObservable.max(Observable.just(1,2,3,4,5,6));

o1.subscribe(new Action1<Integer>() {
    @Override
    public void call(Integer integer) {
        Log.i(TAG, "call: "+integer);
    }
});
登入後複製

9.Count

count函数主要列出发送队列的个数。

Observable<Integer> o1 =Observable.just(1,2,3,4,5,4);
Observable<Integer> count = o1.count();

count.subscribe(new Action1<Integer>() {
    @Override
    public void call(Integer integer) {
            //打印出6
        Log.i(TAG, "call: "+integer);
    }
});
登入後複製

10.Sum

计算Observable发射的数值的和并发射这个和.

RxJava的实现是sumDouble, sumFloat, sumInteger, sumLong,它们不是RxJava核心模块的一部分,属于rxjava-math模块。你可以使用一个函数,计算Observable每一项数据的函数返回值的和。

Observable<Integer> o1 =
            MathObservable.sumInteger(Observable.just(1,2,3,4,5,4));

o1.subscribe(new Action1<Integer>() {
    @Override
    public void call(Integer integer) {
        Log.i(TAG, "call: "+integer);
    }
});
登入後複製

 以上就是深入浅出RxJava_05[转换操作&数学运算]的代码详细介绍的内容,更多相关内容请关注PHP中文网(www.php.cn)!


來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板