如何使用RxJava2过滤Arraylist

时间:2018-02-13 10:10:37

标签: java android arraylist rx-java2

使用RxJava2来过滤列表。不知何故让它发挥作用。但问题是,它只返回Consumer回调列表中的一个项(大小始终为1)

这是代码:

 Observable.fromIterable(arraylist)
                   .filter(new Predicate<BasicListModel>() {
                       @Override
                       public boolean test(BasicListModel model) throws Exception {
                           return true; //returning true for all items in filter
                       }
                   })
                   .toList()
                   .observeOn(Schedulers.computation())
                   .subscribe(new Consumer<List<BasicListModel>>() {
                       @Override
                       public void accept(List<BasicListModel> models) throws Exception {

                               Log.i("TAG"," size:"+models.size());

                       }
                   });

我是RxJAva1或RxJava2的新手。

4 个答案:

答案 0 :(得分:5)

您可以使用正确的迭代进行过滤,如下所示

Observable.fromIterable(offerBasicListModel)
            .observeOn(Schedulers.computation())
            .filter(new Predicate<BasicListModel>() {
                @Override
                public boolean test(BasicListModel model) throws Exception {

                    if (model.isDownloading()) //assume
                        return true; // if true, object will redirect to `doOnNext`
                    else
                        return false;
                }
            })
            .doOnNext(new Consumer<BasicListModel>() {
                @Override
                public void accept(BasicListModel model) throws Exception {
                    Log.d("objects one by one ->",model.getId());
                }
            })
            .toList()
            .subscribe(new Consumer<List<BasicListModel>>() {
                @Override
                public void accept(List<BasicListModel> model) throws Exception {
                    Log.d(TAG, "filtered list size: "+model.size());
                }
            });

如果你支持java 8,那么

Observable.fromIterable(offerBasicListModel)
            .observeOn(Schedulers.computation())
            .filter(BasicListModel::isDownloading)
            .doOnNext(
            model ->Log.d(TAG,"filtered objects one by one ->",model.getId())
            )
            .toList()
            .subscribe(model -> Log.d(TAG, "filtered list size: "+model.size()));

<强>更新

  

自定义用户模型

public class UserModel {

private int age;
private String name;

public UserModel(int age, String name) {
    this.age = age;
    this.name = name;
}

public int getAge() {
    return age;
}

public void setAge(int age) {
    this.age = age;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
} 
}
  

执行年龄在18岁以上的过滤用户

ArrayList<UserModel> userModelArrayList = new ArrayList<>();
    UserModel user;
    for (int i = 0; i < 20; i++) {
        if (i % 2 == 0)
            user = new UserModel(25, "user" + i);
        else
            user = new UserModel(15, "user" + i);

        userModelArrayList.add(user);
    }

    io.reactivex.Observable
            .fromIterable(userModelArrayList)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.computation())
            .filter(userModel -> userModel.getAge() > 18)
            .toList()
            .subscribe(new SingleObserver<List<UserModel>>() {
                @Override
                public void onSubscribe(Disposable d) {
                    /* to do */
                }

                @Override
                public void onSuccess(List<UserModel> userModels) {
                    Log.d("userModels", " after filtering: " + userModels.size());

                }

                @Override
                public void onError(Throwable e) {
                    /* to do */
                }
            });

在这里,我可以在onSuccess()中实现10个已过滤的用户对象。

我建议您首先使用示例代码尝试此方法,如果它正常工作,那么您可以修改并跟踪您确实在哪里做错了。

Result

答案 1 :(得分:0)

您可以尝试在onCompleted上添加Subscriber,以便在列表发出所有值时通知吗?

答案 2 :(得分:0)

与Aks4125解决方案一样,我能够过滤List。但每当我调用Filter函数时,它返回给我不同大小的List。

使用Observer回调修改了我的代码。工作正常,但不得不写一些额外的代码来制作列表,因为它一次只返回一个Object

这是代码:

Observable.fromIterable(arraylist)
                    .filter(new Predicate<BasicListModel>() {
                        @Override
                        public boolean test(BasicListModel model) throws Exception {
                             if(filter){
                                return true;
                                  }else{
                                return false;
                                  }
                    })
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<BasicListModel>() {
                        @Override
                        public void onSubscribe(Disposable disposable) {
                            filteredBasicListModel.clear();
                        }

                        @Override
                        public void onNext(BasicListModel basicListModel) {
                            filteredBasicListModel.add(basicListModel);
                        }

                        @Override
                        public void onError(Throwable throwable) {

                        }

                        @Override
                        public void onComplete() {
                            Log.i("TAG","size :"+filteredBasicListModel.size());
                    });

这对我来说当前是有效的解决方案。如果它可以更好地优化。我愿意接受解决方案。

学习和提高。

答案 3 :(得分:-1)

尝试在.blockingGet()电话后添加toList()。这将消除所有异步性。