1 buffer
buffer操作符周期性地收集源Observable产生的结果到列表中,并把这个列表提交给订阅者,订阅者处理后,清空buffer列表,同时接收下一次收集的结果并提交给订阅者,周而复始需要注意的是,一旦源Observable在产生结果的过程中出现异常,即使buffer已经存在收集到的结果,订阅者会马上收到这个异常,buffer中的结果不会发出。
int num = 1;
public void useBuffer(View view) {
//定义邮件内容
final String[] mails = new String[]{"Here is an email!", "Another email!", "Yet another email!"};
//每隔1秒就随机发布一封邮件
Observable<String> endlessMail = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
if (subscriber.isUnsubscribed()) {
return;
}
Random ran = new Random();
while (true) {
String mail = mails[ran.nextInt(mails.length)];
subscriber.onNext(mail);
if (num == 8) {
subscriber.onError(new Throwable("故意出错"));
}
num++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
subscriber.onError(e);
}
}
}
}).subscribeOn(Schedulers.io());
//把上面产生的邮件内容缓存到列表中,并每隔3秒通知订阅者
endlessMail.buffer(3, TimeUnit.SECONDS)
.subscribe(new Subscriber<List<String>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
Log.e(tag, e.getMessage());
}
@Override
public void onNext(List<String> list) {
Log.e(tag, String.format("You've got %d new messages! Here they are!", list.size()));
for (int i = 0; i < list.size(); i++)
Log.e(tag, "**" + list.get(i).toString());
}
});
}
输出结果
E/tag: You've got 3 new messages! Here they are!
E/tag: **Another email!
E/tag: **Yet another email!
E/tag: **Here is an email!
E/tag: You've got 3 new messages! Here they are!
E/tag: **Here is an email!
E/tag: **Another email!
E/tag: **Another email!
E/tag: 故意出错
当num=8的时候,buffer的第三次收集已经收集了2次事件,但是调用subscriber
.onError(new Throwable(“故意出错”));后,收集的事件并没发出,而这个
错误,订阅者会立即接收到。
2:flatMap
transform the items emitted by an Observable into Observables, then flatten the emissions from those into a single Observable
/**
* flatMap() 的原理是这样的:
* 1. 使用传入的事件对象创建一个 Observable 对象;
* 2. 并不发送这个 Observable, 而是将它激活,于是它开始发送事件;
* 3. 每一个创建出来的 Observable 发送的事件,都被汇入同一个 Observable ,
* 而这个 Observable 负责将这些事件统一交给 Subscriber 的回调方法。
* 这三个步骤,把事件拆成了两级,
* 通过一组新创建的 Observable 将初始的对象『铺平』之后通过统一路径分发了下去
*
*/
public void useFlatMap(View view) {
List<Student> students = new ArrayList<>();
Student.Course course = new Student.Course("语文");
Student.Course course1 = new Student.Course("数学");
List<Student.Course> list = new ArrayList<>();
list.add(course);
list.add(course1);
Student stu1 = new Student();
stu1.setName("homgin");
stu1.setCourseList(list);
Student stu2 = new Student();
stu2.setName("dumingwei");
stu2.setCourseList(list);
students.add(stu1);
students.add(stu2);
Subscriber<Student.Course> subscriber = new Subscriber<Student.Course>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Student.Course course) {
//打印课程的名字
Log.e(tag, course.getLesson());
}
};
Observable.from(students)
.flatMap(new Func1<Student, Observable<Student.Course>>() {
@Override
public Observable<Student.Course> call(Student student) {
//发一个学生事件转化成多个课程事件,一次发出
return Observable.from(student.getCourseList());
}
}).subscribe(subscriber);
}
输出结果 : 语文,数学,语文,数学
3 groupBy
groupBy操作符是对源Observable产生的结果进行分组,形成一个类型为GroupedObservable的结果集,GroupedObservable中存在一个方法为getKey(),可以通过该方法获取结果集的Key值
Observable.interval(1, TimeUnit.SECONDS).take(10).groupBy(new Func1<Long, Long>() {
@Override
public Long call(Long aLong) {
return aLong % 3;
}
}).subscribe(new Action1<GroupedObservable<Long, Long>>() {
@Override
public void call(final GroupedObservable<Long, Long> result) {
result.subscribe(new Action1<Long>() {
@Override
public void call(Long value) {
Log.e(tag, "key:" + result.getKey() + ", value:" + value);
}
});
}
});
//输出结果
09-18 23:03:51.908 20619-21544/? E/tag: key:0, value:0
09-18 23:03:52.904 20619-21544/? E/tag: key:1, value:1
09-18 23:03:53.904 20619-21544/? E/tag: key:2, value:2
09-18 23:03:54.904 20619-21544/? E/tag: key:0, value:3
09-18 23:03:55.904 20619-21544/? E/tag: key:1, value:4
09-18 23:03:56.904 20619-21544/? E/tag: key:2, value:5
09-18 23:03:57.904 20619-21544/? E/tag: key:0, value:6
09-18 23:03:58.904 20619-21544/? E/tag: key:1, value:7
09-18 23:03:59.904 20619-21544/? E/tag: key:2, value:8
09-18 23:04:00.904 20619-21544/? E/tag: key:0, value:9
4 map
transform the items emitted by an Observable by applying a function to each item
Observable.just(1, 2, 3).map(new Func1<Integer, String>() {
@Override
public String call(Integer integer) {
return integer + "string";
}
}).subscribe(new Action1<String>() {
@Override
public void call(String string) {
Log.e(tag, string);
}
});
输出结果:1string,2string,3string
5:scan
scan操作符通过遍历源Observable产生的结果,依次对每一个结果项按照指定规则进行运算,计算后的结果作为下一个迭代项参数,每一次迭代项都会把计算结果输出给订阅者。
Observable.just(1, 2, 3, 4, 5)
.scan(new Func2<Integer, Integer, Integer>() {
@Override
public Integer call(Integer sum, Integer item) {
//参数sum就是上一次的计算结果
return sum + item;
}
}).subscribe(new Subscriber<Integer>() {
@Override
public void onNext(Integer item) {
System.out.println("Next: " + item);
}
@Override
public void onError(Throwable error) {
System.err.println("Error: " + error.getMessage());
}
@Override
public void onCompleted() {
System.out.println("Sequence complete.");
}
});
输出结果
Next: 1
Next: 3
Next: 6
Next: 10
Next: 15
Sequence complete.
6window
window操作符非常类似于buffer操作符,区别在于buffer操作符产生的结果是一个List缓存,而window操作符产生的结果是一个Observable,订阅者可以对这个结果Observable重新进行订阅处理。
Observable.interval(1, TimeUnit.SECONDS).take(12)
.window(3, TimeUnit.SECONDS)
.subscribe(new Action1<Observable<Long>>() {
@Override
public void call(Observable<Long> observable) {
System.out.println("subdivide begin......");
observable.subscribe(new Action1<Long>() {
@Override
public void call(Long aLong) {
System.out.println("Next:" + aLong);
}
});
}
});
运行结果如下:
subdivide begin……
Next:0
Next:1
subdivide begin……
Next:2
Next:3
Next:4
subdivide begin……
Next:5
Next:6
Next:7
subdivide begin……
Next:8
Next:9
Next:10
subdivide begin……
Next:11
结尾:参考链接
【1】http://reactivex.io/documentation/operators.html
【2】http://blog.csdn.net/job_hesc/article/details/46495281