map和flatMap都可以对RxJava传入的数据进行变换。
map对数据进行变换后,可以返回任意值。map对数据的变换是1对1进行的
flatMap对数据变换后,返回ObservableSource对象。可以对数据进行一对多,多对多的变换。flatMap并不保证数据有序。
concatMap与flatMap使用基本一致,它可以保证数据有序
map的使用
Observable.just("学生1", "学生2", "学生3")
.map(new Function<String, String>() {
@Override
public String apply(String s) throws Throwable {
return s;
}
})
.subscribe(t -> {
Log.d("=====", t);
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
输入三条数据,最后subscribe结果也是三条。打印结果为:
=====: 学生1
=====: 学生2
=====: 学生3
- 1
- 2
- 3
flatMap的使用
这里需要使用到一个简单的工具类。
public class Student {
public String name;
public int no;
}
- 1
- 2
- 3
- 4
创建对应数据的方法:
private List<Student> getData() {
List<Student> data = new ArrayList<>();
Student stu = null;
for (int i = 0; i < 5; i ++) {
stu = new Student();
stu.name = "学生" + i;
stu.no = i;
data.add(stu);
}
return data;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
List<Student> mData = getData();
- 1
1对1的情况
Observable.just(mData)
.flatMap(new Function<List<Student>, ObservableSource<?>>() {
@Override
public ObservableSource<?> apply(List<Student> students) throws Throwable {
return Observable.create(new ObservableOnSubscribe<List<Student>>() {
@Override
public void subscribe(@NonNull ObservableEmitter<List<Student>> emitter) throws Throwable {
emitter.onNext(students);
}
});
}
})
.subscribe(t -> {
Log.d("=====", t.toString());
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
从打印日志可以看到,这里输入一个List对象,subscribe中也得到一个List的对象。下面我们来看一对多的情况
=====: [com.example.demorxjava3.Student@35b2f4b, com.example.demorxjava3.Student@53e2d28, com.example.demorxjava3.Student@22b9a41, com.example.demorxjava3.Student@4d6abe6, com.example.demorxjava3.Student@1ab7527]
- 1
1对多
Observable.just(mData)
.flatMap(new Function<List<Student>, ObservableSource<?>>() {
@Override
public ObservableSource<?> apply(List<Student> students) throws Throwable {
return Observable.fromIterable(students);
}
})
.subscribe(t -> {
Log.d("=====", t.toString());
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
从打印结果可以看到,这里分别打印了五个Student对象
=====: com.example.demorxjava3.Student@35b2f4b
=====: com.example.demorxjava3.Student@53e2d28
=====: com.example.demorxjava3.Student@22b9a41
=====: com.example.demorxjava3.Student@4d6abe6
=====: com.example.demorxjava3.Student@1ab7527
- 1
- 2
- 3
- 4
- 5
多对多(减少对象)
Observable.just("学生1", "学生2", "学生3")
.flatMap(new Function<String, ObservableSource<?>>() {
@Override
public ObservableSource<?> apply(String s) throws Throwable {
if ("学生2".equals(s)) {
return Observable.empty();
}
return Observable.just(s);
}
})
.subscribe(t -> {
Log.d("=====", t.toString());
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
在这里我们输入了三条数据,在flatMap中,第二条数据返回的是空Observable对象,会被忽略,所以我们会看到最后数据只剩下两条。
=====: 学生1
=====: 学生3
- 1
- 2
多对多(增加对象)
Observable.just("学生1", "学生2", "学生3")
.flatMap(new Function<String, ObservableSource<?>>() {
@Override
public ObservableSource<?> apply(String s) throws Throwable {
if ("学生2".equals(s)) {
return Observable.just(s, "学生N");
}
return Observable.just(s);
}
})
.subscribe(t -> {
Log.d("=====", t.toString());
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
这里我们增加了一个学生N。
=====: 学生1
=====: 学生2
=====: 学生N
=====: 学生3
- 1
- 2
- 3
- 4
flatMap并不保证数据有序
Observable.just("学生1", "学生2", "学生3", "学生4", "学生5")
.flatMap(new Function<String, ObservableSource<?>>() {
@Override
public ObservableSource<?> apply(String s) throws Throwable {
return Observable.just(s).delay(200, TimeUnit.MILLISECONDS);
}
})
.subscribe(t -> {
Log.d("=====", t.toString());
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
其中一次输出结果为:
=====: 学生2
=====: 学生1
=====: 学生3
=====: 学生4
=====: 学生5
- 1
- 2
- 3
- 4
- 5
如果想让数据能保持有序输出则需要用到concatMap
concatMap
concatMap的使用与flatMap基本一致,它可以保证输出数据有序。