RxJava operator usage (2)

Overview: The last article briefly introduced the use of the Observable creation operator in Rxjava and its meaning. Because it is relatively simple, it is written roughly. This article will continue to introduce some operators about type transformation and the power of transformation operators. The expense is that no additional processing is required, and the data can be quickly processed and converted to obtain the required type, and the code and logic are clear and easy to understand. Quoting a picture on the Internet:


Map()

map(): Realize the transformation of the sent data according to certain rules to output different types
Observable.just(1,2,3,4)
                .map(new Function<Integer, String>() {
                    @Override
                    public String apply(Integer integer) throws Exception {
                        return String.valueOf(integer) + "String";
                    }
                }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                
            }
        });
Output result:
02-05 11:19:58.702 30540-30540/com.example.administrator.sdk E/===: 1String
02-05 11:19:58.702 30540-30540/com.example.administrator.sdk E/===: 2String
02-05 11:19:58.702 30540-30540/com.example.administrator.sdk E/===: 3String
02-05 11:19:58.702 30540-30540/com.example.administrator.sdk E/===: 4String

FlatMap()

flatMap(): It can also implement type replacement, but the function is more powerful than map(), which requires the type data wrapped by Observable to be returned. Usage:
Observable.just(1,2,3,4)
                .flatMap(new Function<Integer, ObservableSource<String>>() {
                    @Override
                    public ObservableSource<String> apply(Integer integer) throws Exception {
                        return Observable.just(integer+"String");
                    }
                }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.e("flat===", s);
            }
        });
The difference between flatMap() and map():
  • Different return types: It can be seen from the above two codes that the return types of the two are different. map() returns the specific data to be returned, while flatMap() returns the data wrapped by Observable, so the data can continue to be distributed
  • More powerful: Because the returned Observable is still Observable, it is more flexible and convenient to use
Example: There is a set of stores, each store sells a variety of products, the data source is as follows:
private void initData() {
        Product phone_apple = new Product("手机");
        Product computer_apple = new Product("电脑");
        Product pad_apple = new Product("平板");
        ArrayList<Product> products_apple = new ArrayList<>();
        products_apple.add(phone_apple);
        products_apple.add(computer_apple);
        products_apple.add(pad_apple);
        apple = new Shop("苹果", products_apple);

        Product phone_xiaomi = new Product("手机");
        Product computer_xiaomi = new Product("电脑");
        Product pad_xiaomi = new Product("平板");
        Product light_xiaomi = new Product("灯");
        ArrayList<Product> products_xiaomi = new ArrayList<>();
        products_xiaomi.add(phone_xiaomi);
        products_xiaomi.add(computer_xiaomi);
        products_xiaomi.add(pad_xiaomi);
        products_xiaomi.add(light_xiaomi);
        xiaomi = new Shop("苹果", products_xiaomi);
    }
Now to print the product name of each store, use map to achieve:
  Observable.fromIterable(shops)
                .map(new Function<Shop, ArrayList<Product>>() {
                    @Override
                    public ArrayList<Product> apply(Shop shop) throws Exception {
                        Log.e("Shop Name:", shop.getName()+"Sold items are:");
                        return shop.getProducts();
                    }
                })
                .subscribe(new Consumer<ArrayList<Product>>() {
                    @Override
                    public void accept(ArrayList<Product> products) throws Exception {
                        for (Product product : products) {
                            Log.e("Product == ", product.getName());
                        }
                    }
                });
Output result:
02-05 11:58:15.916 31479-31479/? E/==:  --------------------------map-----------------------------
02-05 11:58:15.930 31479-31479/? E/ Store Name: : Apple sells:
02-05 11:58:15.930 31479-31479/? E/Product ==: Mobile
02-05 11:58:15.930 31479-31479/? E/Product ==: Computer
02-05 11:58:15.930 31479-31479/? E/Product ==: Tablet
02-05 11:58:15.930 31479-31479/? E/ Store Name: : Apple sells:
02-05 11:58:15.930 31479-31479/? E/Product ==: Mobile
02-05 11:58:15.930 31479-31479/? E/Product ==: Computer
02-05 11:58:15.930 31479-31479/? E/Product ==: Tablet
02-05 11: 58: 15.930 31479-31479 /? E / Product ==: Light
Implemented using flatMap:
Observable.fromIterable(shops)
                .flatMap(new Function<Shop, ObservableSource<Product>>() {
                    @Override
                    public ObservableSource<Product> apply(Shop shop) throws Exception {
                        Log.e("Shop Name:", shop.getName()+"Sold items are:");
                        return Observable.fromIterable(shop.getProducts());
                    }
                })
                .subscribe(new Consumer<Product>() {
            @Override
            public void accept(Product product) throws Exception {
                Log.e("Product == ", product.getName());
            }
        });
Output result:
02-05 11:58:15.931 31479-31479/? E/==:  --------------------------flatMap-----------------------------
02-05 11:58:15.937 31479-31479/? E/Store Name:: Apple sells products:
02-05 11:58:15.937 31479-31479/? E/Product ==: Mobile
02-05 11:58:15.937 31479-31479/? E/Product ==: Computer
02-05 11:58:15.937 31479-31479/? E/Product ==: Tablet
02-05 11:58:15.937 31479-31479/? E/Store Name:: Apple sells products:
02-05 11:58:15.937 31479-31479/? E/Product ==: Mobile
02-05 11:58:15.937 31479-31479/? E/Product ==: Computer
02-05 11:58:15.938 31479-31479/? E/Product ==: Tablet
02-05 11: 58: 15.938 31479-31479 /? E / Product ==: Light
Conclusion: The above implementation of map can only return the collection of Products. To output each product, you need to use a loop to traverse, and the one using flatMap gets each store and directly uses Observable to distribute their products again, and then directly in the observer. Just output the product name, which is simpler and clearer

ConcatMap()

The same as the use of flatMap, the difference is that flatMap will generate a new set of data sequences after the transformation, and the order may be different from the sending order, while the order generated by ConcatMap is consistent with the sending order;

Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                e.onNext(1);
                e.onNext(2);
                e.onNext(3);
            }
        }).concatMap(new Function<Integer, ObservableSource<String>>() {
            @Override
            public ObservableSource<String> apply(Integer integer) throws Exception {
                ArrayList<String> strings = new ArrayList<>();
                for (int i = 0; i < 3; i++) {
                    strings.add(integer + "===" + i);
                }
                return Observable.fromIterable(strings);
            }
        })
                .subscribe(new Consumer<String>() {
                    @Override
                    public void accept(String s) throws Exception {
                        Log.e("Integer==", s);
                    }
                });
Output result:
02-05 12:19:05.148 32258-32258/com.example.administrator.sdk E/Integer==: 1===0
02-05 12:19:05.148 32258-32258/com.example.administrator.sdk E/Integer==: 1===1
02-05 12:19:05.148 32258-32258/com.example.administrator.sdk E/Integer==: 1===2
02-05 12:19:05.148 32258-32258/com.example.administrator.sdk E/Integer==: 2===0
02-05 12:19:05.148 32258-32258/com.example.administrator.sdk E/Integer==: 2===1
02-05 12:19:05.148 32258-32258/com.example.administrator.sdk E/Integer==: 2===2
02-05 12:19:05.148 32258-32258/com.example.administrator.sdk E/Integer==: 3===0
02-05 12:19:05.149 32258-32258/com.example.administrator.sdk E/Integer==: 3===1
02-05 12:19:05.149 32258-32258/com.example.administrator.sdk E/Integer==: 3===2

Buffer()

Each time a part of the data is extracted into the cache, and sent directly from the cache Parameters: capacity, step size
Observable.just(1,2,3,4,5,6)
                .buffer(3,2)
                .subscribe(new Consumer<List<Integer>>() {
                    @Override
                    public void accept(List<Integer> integers) throws Exception {
                        Log.e("integers===", integers.size()+"");
                        for (Integer integer : integers){
                            Log.e("integer = ",integer + "");
                        }
                    }
                });
According to the above logic, the cache length is 3, the first time, 1, 2, 3, take two each time, the second one is 3, 4, 5, and so on:
02-05 13:47:53.107 1123-1123/? E/integers===: 3
02-05 13: 47: 53.107 1123-1123 /? And / integer =: 1
02-05 13: 47: 53.107 1123-1123 /? And / integer =: 2
02-05 13: 47: 53.107 1123-1123 /? And / integer =: 3
02-05 13:47:53.107 1123-1123/? E/integers===: 3
02-05 13: 47: 53.107 1123-1123 /? And / integer =: 3
02-05 13: 47: 53.108 1123-1123 /? And / integer =: 4
02-05 13: 47: 53.108 1123-1123 /? And / integer =: 5
02-05 13:47:53.108 1123-1123/? E/integers===: 2
02-05 13: 47: 53.108 1123-1123 /? And / integer =: 5
02-05 13: 47: 53.108 1123-1123 /? And / integer =: 6
When you see that the final return is a collection, have you ever thought of the flatMap above, you can output directly without using the collection loop, and now rewrite:
Observable.just(1,2,3,4,5,6)
                .buffer(3,2)
                .flatMap(new Function<List<Integer>, ObservableSource<Integer>>() {
                    @Override
                    public ObservableSource<Integer> apply(List<Integer> integers) throws Exception {
                        return Observable.fromIterable(integers);
                    }
                }).subscribe(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) throws Exception {
                Log.e("integer = ",integer + "");
            }
        });
At this point, the transformation operators in RxJava have been introduced. The transformation operators are more convenient to use and can also meet many actual development needs. I will continue to introduce other operators later.







Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325773437&siteId=291194637