Filter operator that performs conditional filtering operations on the data stream, like a quality inspector on a stream, to reject parts that do not conform to the rules.

Distinct operator.

Suppress (filter out) duplicate data items. In a nutshell, it’s weight loss.

  • For example, you can use the Distinct operator in a List that has multiple duplicates and needs to be iterated to eliminate duplicates.
Observable.fromIterable(mItems) .distinct() .toList() .toObservable() .as(RxLifecycleUtil.bindLifecycle(this)) .subscribe(new Consumer<List<Object>>() { @Override public void accept(List<Object> objects) throws Exception { //... }});Copy the code

ElementAt operator.

Only the NTH data is transmitted. Arraylist.get (index) similar to a collection. Fetch data for the corresponding position. In RxJava event flow, only data events are sent at a specified location.

  • For example, RecyclerView Adapter data set, I already know the location of the data, use the corner to find out, and then update the list control.
int index = 0;
        Observable.fromIterable(mItems)
                .elementAt(index)
                .cast(SingleSelectOptionModel.class)
                .as(RxLifecycleUtil.bindLifecycle(this))
                .subscribe(new Consumer<SingleSelectOptionModel>() {
                    @Override
                    public void accept(SingleSelectOptionModel optionModel) throws Exception {
                        optionModel.setSelect(true); mAdapter.notifyItemChanged(index); }});Copy the code

FirstElement operator.

  • In fact, if you simply want the first item, there is another operator called firstElement, which is the same as elementAt(index), except that it always takes the first item out. If you look at the source code, it’s called elementAt() and passes in the argument 0. So both operators have the same effect, except that RxJava provides firstElement for the usual firstElement fetching operation.
Observable.fromIterable(mItems)
                .filter(new Predicate<Object>() {
                    @Override
                    public boolean test(Object itemModel) throws Exception {
                        returnitemModel instanceof SingleSelectOptionModel; } }) .cast(SingleSelectOptionModel.class) .firstElement() .toObservable() .as(RxLifecycleUtil.bindLifecycle(this)) .subscribe(new Consumer<SingleSelectOptionModel>() { @Override public void accept(SingleSelectOptionModel singleSelectOptionModel) throws Exception { //... }});Copy the code

Filter operator.

Only data items that pass the predicate test are emitted. It’s basically a filter, passing in a Predicate interface argument, overriding the test method, returning true to pass, and false to filter out.

  • For example, the search button of the search function, when clicked, determines whether there is input text, whether the text is empty or empty string. Using the filter operator, untyped text is filtered out and Toast prompts the user.
RxUtil.click(vSearch)
                .map(new Function<Object, String>() {
                    @Override
                    public String apply(Object o) throws Exception {
                        return vSearchEdit.getText().toString().trim();
                    }
                })
                .filter(new Predicate<String>() {
                    @Override
                    public boolean test(String inputText) throws Exception {
                        boolean isEmpty = TextUtils.isEmpty(inputText);
                        if (isEmpty) {
                            showToast(R.string.recommend_search_input_empty_tip);
                        }
                        return !isEmpty;
                    }
                })
                .as(RxLifecycleUtil.bindLifecycle(this))
                .subscribe(new Consumer<String>() {
                    @Override
                    public void accept(String inputText) throws Exception {
                        search(inputText);
                    }
                });
Copy the code

The first and last operators.

First means take out the first event to send, and last means take out the last event to send, and they need to pass a defaultItem parameter as the default value to send if not found.

  • For example, the same function as local search, looks up the data set, determines whether the data for the specified keyword exists (there may be multiple, but I only need to find the first one), and sends a default data if not. The same goes for Last.
Observable.fromIterable(mItems)
                .filter(new Predicate<Object>() {
                    @Override
                    public boolean test(Object itemModel) throws Exception {
                        return itemModel instanceof SingleSelectOptionModel;
                    }
                })
                .cast(SingleSelectOptionModel.class)
                .filter(new Predicate<SingleSelectOptionModel>() {
                    @Override
                    public boolean test(SingleSelectOptionModel model) throws Exception {
                        return "What will happen to us?".equals(model.getTitle());
                    }
                })
                .first(new SingleSelectOptionModel("Can't find it.")) .toObservable() .as(RxLifecycleUtil.bindLifecycle(this)) .subscribe(new Consumer<SingleSelectOptionModel>() { @Override public void accept(SingleSelectOptionModel singleSelectOptionModel) throws Exception { //... }});Copy the code

Skip operator.

Suppress the first N data emitted by an Observable. The first number of events that are skipped.

  • For example, the observation data source will initially send a default value, which we may not need, so we can use the skip operator to skip the first sent event.
RxLunarDataTimePicker. PickChange (mDataTimePopupDialog) / / ignore a began to send the initialization of the default values. The skip (1) .as(RxLifecycleUtil.bindLifecycle(this)) .subscribe(new Consumer<LunarDataTimePickInfo>() { @Override public void accept(LunarDataTimePickInfo info) throws Exception { inttype = info.getType();
                        CalendarTypeEnum calendarTypeEnum;
                        if (DatePickerView.DATE_TYPE_SOLAR == type) {
                            calendarTypeEnum = CalendarTypeEnum.SOLAR;
                        } else if (DatePickerView.DATE_TYPE_LUNAR == type) {
                            calendarTypeEnum = CalendarTypeEnum.LUNAR;
                        } else{ calendarTypeEnum = CalendarTypeEnum.SOLAR; } mCalendar.set(Calendar.YEAR, info.getYear()); mCalendar.set(Calendar.MONTH, info.getMonthOfYear() - 1); mCalendar.set(Calendar.DAY_OF_MONTH, info.getDayOfMonth()); mCalendar.set(Calendar.HOUR_OF_DAY, info.getHour()); mCalendar.set(Calendar.MINUTE, 0); mCalendar.set(Calendar.MILLISECOND, 0); updateBirthday(mCalendar.getTime().getTime(), calendarTypeEnum); }}, new Consumer<Throwable>() { @Override public void accept(Throwable throwable) throws Exception { throwable.printStackTrace(); }});Copy the code

SkipLast operator.

Skip skipLast skips a specified number of events, just as skip skipLast skips a specified number of events, starting from the back.

The take operator. Only the first N entries are transmitted. Start from the front and keep a specified number of events.

  • For example, for the requirement of adding pictures in wechat moments, after selecting multiple pictures, the path path of the picture needs to be bound to the Model of the item. But Items are all the Items, and there will be more selected image Items than we want to set, so we can use the take operator. Even if we go through the whole batch of Items, we just start at the front and specify the Model of the number of images (why start from the front? After selecting the image, you need to fill in the image address from the beginning, and then use the ZIP operator and select the image path set to pair one by one. This completes the process of converting the placeholder image to set the image data
// Specify the number of, Not set image placeholder observables < PressQuestionUploadImageModel > listItemObservable = observables. FromIterable (mItems). The filter (new Predicate<Object>() { @Override public booleantest(Object target) throws Exception {
                        returntarget instanceof PressQuestionUploadImageModel && ((PressQuestionUploadImageModel) target).getPicFilePath() == null; }}). Cast (PressQuestionUploadImageModel. Class) / / restrictions send only not set pictures of a specified number. Take (imgPaths. The size ());return Observable.zip(listItemObservable, Observable.fromIterable(imgPaths), new BiFunction<PressQuestionUploadImageModel, String, PressQuestionUploadImageModel>() {
            @Override
            public PressQuestionUploadImageModel apply(PressQuestionUploadImageModel model, String path) throws Exception {
                model.setPicFilePath(path);
                returnmodel; }})Copy the code

TakeLast operator.

Like take, take reserves a specified number of events from the front, whereas takeLast starts from the back, and the takeLast operator can be used if there is a need to populate from the back.