Jolson Da Costa
Jolson Da Costa

Reputation: 1105

How to filter Arraylist with RxJava2

WAnt to filter list with RxJava2. somehow got it working. but the prob is, it is returning only one item in List in Consumer callback(size is always 1)

here is the code:

 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());

                       }
                   });

i am new to RxJAva1 or RxJava2.

Upvotes: 1

Views: 2648

Answers (4)

Aks4125
Aks4125

Reputation: 5720

You can filter with proper iteration as followed

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());
                }
            });

if you're supporting java 8, then

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()));

UPDATE

Custom User model

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;
} 
}

perform filtering user with age above 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 */
                }
            });

Here I am able to achieve 10 filtered user objects in onSuccess().

I suggest you to try this approach first using sample code if it is working then you can modify and trace where exactly you're doing wrong.

Result

Upvotes: 6

Jolson Da Costa
Jolson Da Costa

Reputation: 1105

as with Aks4125 solution i was able to filter List. but everytime i called Filter function it returned me different sized List.

modified my code with Observer callback. worked fine but had to write little extra code to make the list, as it was returning one Object at a time.

here is the code:

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());
                    });

this is working solution to me currently. if it can be optimized any better. am open to solution.

Learning and Improving.

Upvotes: 0

urgentx
urgentx

Reputation: 3931

Try adding .blockingGet() after your toList() call. This will remove all asynchronicity.

Upvotes: -1

Abdullah Aftab
Abdullah Aftab

Reputation: 50

Can you try adding onCompleted on your Subscriber to notify when the list has emitted all the values?

Upvotes: 0

Related Questions