Rx java RxJava2。处理列表中对象的不同属性

Rx java RxJava2。处理列表中对象的不同属性,rx-java,rx-java2,Rx Java,Rx Java2,假定 有一个类User,具有两个属性name和age 我们得到一个用户列表 我们需要处理每个用户的两个属性 是否可以同时处理每个用户的两个属性 我知道下面的代码不正确。但是如何使它正确呢?也许有操作员让它工作 Observable.fromIterable(users) .map(user -> user.name) .map(string -> new NameVM(string)) .map(user -> user.age) .map(in

假定

  • 有一个类User,具有两个属性nameage
  • 我们得到一个用户列表
  • 我们需要处理每个用户的两个属性
  • 是否可以同时处理每个用户的两个属性

    我知道下面的代码不正确。但是如何使它正确呢?也许有操作员让它工作

    Observable.fromIterable(users)
        .map(user -> user.name)
        .map(string -> new NameVM(string))
        .map(user -> user.age)
        .map(int -> new AgeVM(int))
    
    我只有一个想法,但我不太喜欢

    Observable.fromIterable(users)
        .doOnNext(user -> new NameVM(string))
        .map(user -> user.age)
        .map(int -> new AgeVM(int))
    

    我不知道你想做什么,但从这个问题上看,我认为你有一个可观察的
    用户列表
    ,你需要处理每个用户的
    姓名
    年龄
    ,最后使用更新的
    用户
    数据。为此,为什么不能使用单个
    map
    操作符

            Observable.fromIterable(users)
                .map(user -> {
                    user.name =//do something with name);
                    user.age = // do something with age);
                    return user;
                }).subscribe(user -> {
                    // here you get the result with processed user object
                });
    

    您可以将这两个属性都作为单个属性处理,然后将结果压缩在一起,并使用flatMapSingle进行flatMap。在doOnNext中,每个拉链都有一个容器

    @Test
      void name2() throws Exception {
        List<User> users =
            Arrays.asList(
                new User("hans", 30), new User("leon", 66), new User("Uwe", 45), new User("Michi", 23));
    
        Observable<Container> containerObservable =
            Observable.fromIterable(users)
                .flatMapSingle(
                    user -> {
                      Single<ProcessedAge> processedAgeSingle = processeAge(user.age);
                      Single<ProcessedUserName> processedUserNameSingle =
                          processeUserName(user.userName);
    
                      return Single.zip(
                          processedAgeSingle,
                          processedUserNameSingle,
                          (age, name) -> {
                            return new Container(age, name);
                          });
                    })
                .doOnNext(System.out::println);
    
        containerObservable.test().await().assertValueCount(4);
      }
    
      private Single<ProcessedAge> processeAge(int age) {
        return Single.just(new ProcessedAge());
      }
    
      private Single<ProcessedUserName> processeUserName(String userName) {
        return Single.just(new ProcessedUserName());
      }
    
      class User {
        String userName;
        int age;
    
        public User(String userName, int age) {
          this.userName = userName;
          this.age = age;
        }
      }
    
      class ProcessedUserName {}
    
      class ProcessedAge {}
    
      class Container {
        ProcessedUserName userNameResult;
        ProcessedAge ageResult;
    
        public Container(ProcessedAge age, ProcessedUserName name) {
          this.userNameResult = name;
          this.ageResult = age;
        }
    
        @Override
        public String toString() {
          return "Container{" + "userNameResult=" + userNameResult + ", ageResult=" + ageResult + '}';
        }
      }
    
    @测试
    void name2()引发异常{
    列出用户=
    Arrays.asList(
    新用户(“hans”,30),新用户(“leon”,66),新用户(“Uwe”,45),新用户(“Michi”,23));
    可观测的容器可观测的=
    可观察的。从可观察的(用户)
    .flatMapSingle(
    用户->{
    单个ProcessedAgesSingle=processeAge(user.age);
    单进程服务器名称单=
    processeUserName(user.userName);
    返回Single.zip(
    加工单体,
    processedUserNameSingle,
    (年龄、姓名)->{
    返回新容器(年龄、名称);
    });
    })
    .doOnNext(System.out::println);
    containerObservable.test().await().assertValueCount(4);
    }
    专用单进程(int age){
    返回Single.just(newprocessedage());
    }
    私有单进程userName(字符串用户名){
    返回Single.just(newprocessedUserName());
    }
    类用户{
    字符串用户名;
    智力年龄;
    公共用户(字符串用户名,整数){
    this.userName=用户名;
    这个。年龄=年龄;
    }
    }
    类ProcessedUserName{}
    类ProcessedAge{}
    类容器{
    ProcessedUserName用户名结果;
    经处理的ageResult;
    公共容器(ProcessedAge年龄、ProcessedUserName名称){
    this.usernamesult=name;
    this.ageResult=年龄;
    }
    @凌驾
    公共字符串toString(){
    返回“Container{“+”usernamesult=“+usernamesult+”,ageResult=“+ageResult+'}”;
    }
    }
    
    我最终得到了一个容器解决方案

    class ContainerVM {
        public NameVM nameVM;
        public AgeVM ageVM;
    }
    
    Observable.fromIterable(users)
        .map(user -> buildContainerVM(user));
    
    private ContainerVM buildContainerVM(User user) {
        ContainerVM containerVM = new ContainerVM();
        containerVM.nameVM = new NameVM(user.name);
        containerVM.ageVM = new AgeVM(user.age);
    }
    

    名称和年龄的处理是否应该在同一类型async上完成?name/age process->returntype的结果是什么?刚刚通过返回someVM修改了我的问题。处理这两个结果,然后返回一个包含这两个结果的新容器是否足够?在下一个操作符中,您将得到NameVM和AgetVM?的结果,实际上最终得到的是容器解决方案,但比您的回答中的结果要简单一点。完全不建议在一个管道步骤中修改对象。你应该创建一个新的,并传递下来,或使用doOnNext的副作用。但是请记住,通过管道步骤传递的对象应该是不可变的。我不想修改用户对象,而是创建一个将对象与名称和年龄分开的对象。看到我的修改了吗