概述:上篇文章简单的介绍了Rxjava中Observable的创建操作符的使用和其代表的意义,因为比较简单所以写的比较粗略,本文将继续介绍一些关于类型变换的操作符,变换操作符的强大支出在于不需要额外的处理,可以快速的将数据进行处理和转换,得到需要的类型且代码和逻辑清晰易懂,引用网上的一张图片:
map():实现对发送的数据按照一定的规则进行转换,达到输出不同的类型
Observable.just(1,2,3,4)
.map(new Function() {
@Override
public String apply(Integer integer) throws Exception {
return String.valueOf(integer) + "String";
}
}).subscribe(new Consumer() {
@Override
public void accept(String s) throws Exception {
}
});
输出结果:
02-05 11:19:58.702 30540-30540/com.example.administrator.sdk E/===: 1String
02-05 11:19:58.702 30540-30540/com.example.administrator.sdk E/===: 2String
02-05 11:19:58.702 30540-30540/com.example.administrator.sdk E/===: 3String
02-05 11:19:58.702 30540-30540/com.example.administrator.sdk E/===: 4String
flatMap():也可实现类型的装换,但功能比map()更加强大,它要求返回的时被Observable包裹的类型数据,用法:
Observable.just(1,2,3,4)
.flatMap(new Function>() {
@Override
public ObservableSource apply(Integer integer) throws Exception {
return Observable.just(integer+"String");
}
}).subscribe(new Consumer() {
@Override
public void accept(String s) throws Exception {
Log.e("flat===", s);
}
});
flatMap()与map() 的不同:
实例:有一组店铺集合,每个店铺售卖多种商品,数据源如下:
private void initData() {
Product phone_apple = new Product("手机");
Product computer_apple = new Product("电脑");
Product pad_apple = new Product("平板");
ArrayList products_apple = new ArrayList<>();
products_apple.add(phone_apple);
products_apple.add(computer_apple);
products_apple.add(pad_apple);
apple = new Shop("苹果", products_apple);
Product phone_xiaomi = new Product("手机");
Product computer_xiaomi = new Product("电脑");
Product pad_xiaomi = new Product("平板");
Product light_xiaomi = new Product("灯");
ArrayList products_xiaomi = new ArrayList<>();
products_xiaomi.add(phone_xiaomi);
products_xiaomi.add(computer_xiaomi);
products_xiaomi.add(pad_xiaomi);
products_xiaomi.add(light_xiaomi);
xiaomi = new Shop("苹果", products_xiaomi);
}
现在要打印每家店铺的商品名称,使用map实现:
Observable.fromIterable(shops)
.map(new Function>() {
@Override
public ArrayList apply(Shop shop) throws Exception {
Log.e("商店名称:", shop.getName()+"售卖商品有:");
return shop.getProducts();
}
})
.subscribe(new Consumer>() {
@Override
public void accept(ArrayList products) throws Exception {
for (Product product : products) {
Log.e("Product == ", product.getName());
}
}
});
输出结果:
02-05 11:58:15.916 31479-31479/? E/==: --------------------------map-----------------------------
02-05 11:58:15.930 31479-31479/? E/商店名称:: 苹果售卖商品有:
02-05 11:58:15.930 31479-31479/? E/Product ==: 手机
02-05 11:58:15.930 31479-31479/? E/Product ==: 电脑
02-05 11:58:15.930 31479-31479/? E/Product ==: 平板
02-05 11:58:15.930 31479-31479/? E/商店名称:: 苹果售卖商品有:
02-05 11:58:15.930 31479-31479/? E/Product ==: 手机
02-05 11:58:15.930 31479-31479/? E/Product ==: 电脑
02-05 11:58:15.930 31479-31479/? E/Product ==: 平板
02-05 11:58:15.930 31479-31479/? E/Product ==: 灯
使用flatMap实现:
Observable.fromIterable(shops)
.flatMap(new Function>() {
@Override
public ObservableSource apply(Shop shop) throws Exception {
Log.e("商店名称:", shop.getName()+"售卖商品有:");
return Observable.fromIterable(shop.getProducts());
}
})
.subscribe(new Consumer() {
@Override
public void accept(Product product) throws Exception {
Log.e("Product == ", product.getName());
}
});
输出结果:
02-05 11:58:15.931 31479-31479/? E/==: --------------------------flatMap-----------------------------
02-05 11:58:15.937 31479-31479/? E/商店名称:: 苹果售卖商品有:
02-05 11:58:15.937 31479-31479/? E/Product ==: 手机
02-05 11:58:15.937 31479-31479/? E/Product ==: 电脑
02-05 11:58:15.937 31479-31479/? E/Product ==: 平板
02-05 11:58:15.937 31479-31479/? E/商店名称:: 苹果售卖商品有:
02-05 11:58:15.937 31479-31479/? E/Product ==: 手机
02-05 11:58:15.937 31479-31479/? E/Product ==: 电脑
02-05 11:58:15.938 31479-31479/? E/Product ==: 平板
02-05 11:58:15.938 31479-31479/? E/Product ==: 灯
结论:上面使用map实现时只能返回Product的集合,要想输出每个商品需要使用循环去遍历,而使用flatMap的那个获得每个商店后直接再次采用Observable分发他们的商品,然后在观察者直接输出商品名称即可,更简单更清晰
与flatMap的使用相同,其别在于flatMap在变换之后会生成一组新的数据序列,顺序与发送的可能会不同,而ConcatMap产生的顺序与发送的顺序一致;
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onNext(3);
}
}).concatMap(new Function>() {
@Override
public ObservableSource apply(Integer integer) throws Exception {
ArrayList strings = new ArrayList<>();
for (int i = 0; i < 3; i++) {
strings.add(integer + "===" + i);
}
return Observable.fromIterable(strings);
}
})
.subscribe(new Consumer() {
@Override
public void accept(String s) throws Exception {
Log.e("Integer==", s);
}
});
输出结果:
02-05 12:19:05.148 32258-32258/com.example.administrator.sdk E/Integer==: 1===0
02-05 12:19:05.148 32258-32258/com.example.administrator.sdk E/Integer==: 1===1
02-05 12:19:05.148 32258-32258/com.example.administrator.sdk E/Integer==: 1===2
02-05 12:19:05.148 32258-32258/com.example.administrator.sdk E/Integer==: 2===0
02-05 12:19:05.148 32258-32258/com.example.administrator.sdk E/Integer==: 2===1
02-05 12:19:05.148 32258-32258/com.example.administrator.sdk E/Integer==: 2===2
02-05 12:19:05.148 32258-32258/com.example.administrator.sdk E/Integer==: 3===0
02-05 12:19:05.149 32258-32258/com.example.administrator.sdk E/Integer==: 3===1
02-05 12:19:05.149 32258-32258/com.example.administrator.sdk E/Integer==: 3===2
每次提取一部分数据到缓存中,发送直接从缓存发送 参数:容量,步长
Observable.just(1,2,3,4,5,6)
.buffer(3,2)
.subscribe(new Consumer>() {
@Override
public void accept(List integers) throws Exception {
Log.e("integers===", integers.size()+"");
for (Integer integer : integers){
Log.e("integer = ",integer + "");
}
}
});
按照上面的逻辑,缓存长度为3,第一次,1,2,3,每次取两个,第二个为3,4,5,依次类推:
02-05 13:47:53.107 1123-1123/? E/integers===: 3
02-05 13:47:53.107 1123-1123/? E/integer =: 1
02-05 13:47:53.107 1123-1123/? E/integer =: 2
02-05 13:47:53.107 1123-1123/? E/integer =: 3
02-05 13:47:53.107 1123-1123/? E/integers===: 3
02-05 13:47:53.107 1123-1123/? E/integer =: 3
02-05 13:47:53.108 1123-1123/? E/integer =: 4
02-05 13:47:53.108 1123-1123/? E/integer =: 5
02-05 13:47:53.108 1123-1123/? E/integers===: 2
02-05 13:47:53.108 1123-1123/? E/integer =: 5
02-05 13:47:53.108 1123-1123/? E/integer =: 6
当看到最后返回的是个集合,有没有想到上面的flatMap,可以不需要使用集合的循环就可以直接输出,现在改写:
Observable.just(1,2,3,4,5,6)
.buffer(3,2)
.flatMap(new Function, ObservableSource>() {
@Override
public ObservableSource apply(List integers) throws Exception {
return Observable.fromIterable(integers);
}
}).subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.e("integer = ",integer + "");
}
});
到此RxJava中的变换的操作符介绍完了,变换操作符在使用中比较方便,也能满足很多实际开发时的需求,之后会继续介绍其它操作符。