Reputation: 1105
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
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.
Upvotes: 6
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
Reputation: 3931
Try adding .blockingGet()
after your toList()
call. This will remove all asynchronicity.
Upvotes: -1
Reputation: 50
Can you try adding onCompleted
on your Subscriber
to notify when the list has emitted all the values?
Upvotes: 0