【问题标题】:RxAndroid filter Observable<List<Item>>RxAndroid 过滤器 Observable<List<Item>>
【发布时间】:2016-09-19 06:49:57
【问题描述】:

我使用 RxAndroid,我想过滤 Observable&lt;List&lt;Item&gt;&gt; 的结果。

代码如下:

Observable<List<Item>> observable = 
Observable.create((Observable.OnSubscribe<List<Item>>) subscriber -> {
        subscriber.onNext(ItemManager.getItems());
        subscriber.onCompleted();
    });

我想使用.filter() 只获取有效项目。这样做会很完美:

observable.filter(new Func1<Item, Boolean>() {
    @Override
        public Boolean call(Item item) {
            return item.isValid();
    }
});

但是,.filter() 强迫我实现 new Func1() :

observable.filter(new Func1<List<Item>, Boolean>() {
        @Override
            public Boolean call(Item item) {
        }
    });

有人知道如何解决这个问题吗?

提前谢谢你:)

【问题讨论】:

    标签: android rx-java rx-android


    【解决方案1】:
         Observable.defer(() -> Observable.just(ItemManager.getItems())
                .subscribeOn(Schedulers.io())
                .flatMapIterable(items -> items)
                .filter(item -> item.isValid())
                .toList();
    

    【讨论】:

    • 我忘了说 ItemManager.getItems() 必须异步调用,因为它会进行网络调用:/
    • 更新了我的答案
    • 这样他就不会异步调用ItemManager.getItems(),而是异步处理其结果。
    • 抱歉,我没有看到 defer() 电话,+1 给你的回答 ;-)
    • 这里有一篇文章详细介绍了使用 defer 和 fromCallable artemzin.com/blog/… 的不同方式和含义
    【解决方案2】:

    只需使用 from 函数创建 Observable:

        Observable<Item> observable = Observable.from(ItemManager.getItems())
        .filter(new Func1<Item, Boolean>() {
            @Override
            public Boolean call(Item item) {
                return item.isValid();
            }
        });
    
        observable.subscribe(System.out::println);
    

    更新

    由于您需要异步调用ItemManager.getItems(),您需要这样做:

    Observable<List<Item>> observable = 
    Observable.create((Observable.OnSubscribe<Item>) subscriber -> {
            for (Item item : ItemManager.getItems()) {
                subscriber.onNext(item);
            }
    
            subscriber.onCompleted();
        })
    .filter(item -> item.isValid())
    .subscribeOn(Schedulers.io());
    

    这样订阅和对ItemManager.getItems()的调用将在一个io线程上执行。

    【讨论】:

    • 我忘了说 ItemManager.getItems() 必须异步调用,因为它会进行网络调用:/
    • 我真的建议尽可能避免Observable.create
    • @Geralt_Encore 为什么?
    • 这是一个很好的建议。如果您使用 create 创建自己的 Obserable,则必须自己处理错误和完成。
    • 好的,我明白了。谢谢你:)
    【解决方案3】:

    我找到了这个解决方案,但我不知道这是否是一个好方法:

    Observable<List<Item>> observable = 
    Observable.create((Observable.OnSubscribe<Item>) subscriber -> {
            for (Item item : ItemManager.getItems()) {
                subscriber.onNext(item);
            }
    
            subscriber.onCompleted();
        })
        .filter(item -> item.isValid());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-20
      • 1970-01-01
      • 2015-08-27
      • 1970-01-01
      • 2018-05-22
      • 1970-01-01
      • 2017-09-11
      相关资源
      最近更新 更多