需求是获取系统所有的文件,代码如下:
File file = new File(Environment.getExternalStorageDirectory().getPath()); //定义一个被观察者 Observable<File> observable = Observable.just(file) .flatMap(new Function<File, ObservableSource<File>>() { @Override public ObservableSource<File> apply(@NonNull File file) throws Exception { return listFile(file); } }); //定义一个观察者 Observer<File> observer = new Observer<File>() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(File file) { } @Override public void onError(Throwable e) { } @Override public void onComplete() { } }; //订阅 observable.subscribe(observer); } //递归文件, private Observable<File> listFile(File file) { if (file.isDirectory()) { Observable<File> ob = Observable.fromArray(file.listFiles()) .flatMap(new Function<File, ObservableSource<File>>() { @Override public ObservableSource<File> apply(@NonNull File file) throws Exception { return listFile(file); } }); return ob; } else { return Observable.just(file); } }
平时使用FlatMap
的例子,都是集合转换为单个元素,按照“平铺”的思路,比较能理解;这里直接FlatMap
结合递归,搞得人晕晕的,不知道有没有什么好理解的思路?
![]() | 1 secondwtq 2020-02-17 01:13:33 +08:00 ![]() 递归的每一层都保证把这个 File 下的所有文件“平铺”到一个 Observable 里面 |
![]() | 2 zhuangzhuang1988 2020-02-17 10:03:53 +08:00 ![]() 搜下 monad, 简单看下就知道了 |
3 maninfog OP @zhuangzhuang1988 看了一下 更晕了 |
4 bydgg 2020-02-17 11:05:22 +08:00 flatten、map 等,不是 rxjava 里专有的。 flatten ( list of list )-> list //个人理解 flatmap = flatten + map 建议把 recursive function 里的 observable 去掉,只剩下 “输入节点,输出 list of 子节点” 的逻辑,再放到 mapper 里。 |
5 colaman 2020-03-04 19:34:26 +08:00 用上下游来想象这部分代码,递归的 flatmap 在中游,递归的逻辑让每一个 file 都成了一个 Observable,然后把 file 发射出去,然后再往下游发射 |